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..95b941503 --- /dev/null +++ b/der/src/asn1/general_string.rs @@ -0,0 +1,36 @@ +use crate::{BytesRef, DecodeValue, EncodeValue, FixedTag, Header, Length, Reader, Tag, Writer}; + +/// 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 + 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; +} +impl<'a> DecodeValue<'a> for GeneralStringRef<'a> { + type Error = crate::Error; + + fn decode_value>(reader: &mut R, header: Header) -> Result { + Ok(Self { + inner: BytesRef::decode_value(reader, header)?, + }) + } +} +impl EncodeValue for GeneralStringRef<'_> { + fn value_len(&self) -> crate::Result { + self.inner.value_len() + } + + fn encode_value(&self, encoder: &mut impl Writer) -> crate::Result<()> { + self.inner.encode_value(encoder) + } +} diff --git a/gss-api/src/negotiation.rs b/gss-api/src/negotiation.rs index 22a22e59c..4e131c575 100644 --- a/gss-api/src/negotiation.rs +++ b/gss-api/src/negotiation.rs @@ -1,7 +1,7 @@ //! Negotiation-related types use der::{ - AnyRef, Choice, Enumerated, Sequence, - asn1::{BitString, OctetStringRef}, + Choice, Enumerated, Sequence, + asn1::{BitString, GeneralStringRef, OctetStringRef}, }; use crate::MechType; @@ -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>, /// 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. /// @@ -389,7 +383,7 @@ 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().as_bytes() ); }