diff --git a/der/src/reader.rs b/der/src/reader.rs index 91e0f5aa9..a8ab071f0 100644 --- a/der/src/reader.rs +++ b/der/src/reader.rs @@ -5,7 +5,7 @@ pub(crate) mod pem; pub(crate) mod slice; use crate::{ - asn1::{AnyCustomClassExplicit, AnyCustomClassImplicit, ContextSpecificExplicit}, + asn1::{AnyCustomClassExplicit, AnyCustomClassImplicit}, Class, Decode, DecodeValue, Encode, EncodingRules, Error, ErrorKind, FixedTag, Header, Length, Tag, TagMode, TagNumber, }; diff --git a/der/src/tag.rs b/der/src/tag.rs index ef5212c7d..cf0e586b8 100644 --- a/der/src/tag.rs +++ b/der/src/tag.rs @@ -6,10 +6,7 @@ mod mode; mod number; pub use self::{class::Class, mode::TagMode, number::TagNumber}; -pub use self::{ - class::CLASS_APPLICATION, class::CLASS_CONTEXT_SPECIFIC, class::CLASS_PRIVATE, - class::CLASS_UNIVERSAL, -}; +pub use self::{class::CLASS_APPLICATION, class::CLASS_CONTEXT_SPECIFIC, class::CLASS_PRIVATE}; use crate::{Decode, DerOrd, Encode, Error, ErrorKind, Length, Reader, Result, Writer}; use core::{cmp::Ordering, fmt}; diff --git a/der_derive/src/attributes.rs b/der_derive/src/attributes.rs index 59b02c9d0..899a38a9d 100644 --- a/der_derive/src/attributes.rs +++ b/der_derive/src/attributes.rs @@ -228,18 +228,19 @@ impl FieldAttrs { .. } = class.to_tokens(type_params, self.tag_mode); - let context_specific = - if self.tag_mode == TagMode::Implicit || self.extensible || self.is_optional() { - quote! { - #class_type::decode_skipping( - reader - )? - } - } else { - quote! { - #class_type::decode(reader)? - } - }; + // let context_specific = + // if self.tag_mode == TagMode::Implicit || self.extensible || self.is_optional() { + // quote! { + // #class_type::decode_skipping( + // reader + // )? + // } + // } else { + // quote! { + // #class_type::decode_skipping(reader)? + // } + // }; + let context_specific = quote! { #class_type::decode_skipping(reader)? }; if self.is_optional() { if let Some(default) = &self.default { @@ -247,6 +248,10 @@ impl FieldAttrs { } else { quote!(#context_specific.map(|cs| cs.value)) } + // }else{ + // quote!(#context_specific.map(|cs| cs.value)) + // } + //} } else { // TODO(tarcieri): better error handling? let constructed = self.constructed; diff --git a/der_derive/src/sequence/field.rs b/der_derive/src/sequence/field.rs index 721e917a0..5835555be 100644 --- a/der_derive/src/sequence/field.rs +++ b/der_derive/src/sequence/field.rs @@ -324,11 +324,11 @@ mod tests { quote! { let implicit_field = ::der::asn1::ContextSpecific::<>::decode_implicit( reader, - ::der::TagNumber::N0 + ::der::TagNumber(0) )? .ok_or_else(|| { der::Tag::ContextSpecific { - number: ::der::TagNumber::N0, + number: ::der::TagNumber(0), constructed: false } .value_error() @@ -342,7 +342,7 @@ mod tests { field.to_encode_tokens().to_string(), quote! { ::der::asn1::ContextSpecificRef { - tag_number: ::der::TagNumber::N0, + tag_number: ::der::TagNumber(0), tag_mode: ::der::TagMode::Implicit, value: &self.implicit_field, } diff --git a/gss-api/src/lib.rs b/gss-api/src/lib.rs index 59316485d..1a4f50808 100644 --- a/gss-api/src/lib.rs +++ b/gss-api/src/lib.rs @@ -140,7 +140,7 @@ mod tests { AnyRef::new( Tag::ContextSpecific { constructed: true, - number: TagNumber::N0 + number: TagNumber(0) }, &inner_bytes ) @@ -153,7 +153,7 @@ mod tests { inner_context_token: AnyRef::new( Tag::ContextSpecific { constructed: true, - number: TagNumber::N0, + number: TagNumber(0), }, &inner_bytes, ) diff --git a/pkcs1/src/params.rs b/pkcs1/src/params.rs index 52ce89642..5bbcc47da 100644 --- a/pkcs1/src/params.rs +++ b/pkcs1/src/params.rs @@ -2,7 +2,7 @@ use crate::{Error, Result}; use der::{ - asn1::{AnyRef, ContextSpecificRef, ObjectIdentifier}, + asn1::{AnyRef, ContextSpecificExplicitRef, ObjectIdentifier}, oid::AssociatedOid, Decode, DecodeValue, Encode, EncodeValue, FixedTag, Length, Reader, Sequence, Tag, TagMode, TagNumber, Writer, @@ -117,51 +117,46 @@ impl<'a> RsaPssParams<'a> { } } - fn context_specific_hash(&self) -> Option>> { + fn context_specific_hash( + &self, + ) -> Option>> { if self.hash == SHA_1_AI { None } else { - Some(ContextSpecificRef { - tag_number: TagNumber::N0, - tag_mode: TagMode::Explicit, - value: &self.hash, - }) + Some(ContextSpecificExplicitRef { value: &self.hash }) } } fn context_specific_mask_gen( &self, - ) -> Option>>> { + ) -> Option>>> + { if self.mask_gen == default_mgf1_sha1() { None } else { - Some(ContextSpecificRef { - tag_number: TagNumber::N1, - tag_mode: TagMode::Explicit, + Some(ContextSpecificExplicitRef { value: &self.mask_gen, }) } } - fn context_specific_salt_len(&self) -> Option> { + fn context_specific_salt_len(&self) -> Option> { if self.salt_len == RsaPssParams::SALT_LEN_DEFAULT { None } else { - Some(ContextSpecificRef { - tag_number: TagNumber::N2, - tag_mode: TagMode::Explicit, + Some(ContextSpecificExplicitRef { value: &self.salt_len, }) } } - fn context_specific_trailer_field(&self) -> Option> { + fn context_specific_trailer_field( + &self, + ) -> Option> { if self.trailer_field == TrailerField::default() { None } else { - Some(ContextSpecificRef { - tag_number: TagNumber::N3, - tag_mode: TagMode::Explicit, + Some(ContextSpecificExplicitRef { value: &self.trailer_field, }) } @@ -186,16 +181,16 @@ impl<'a> DecodeValue<'a> for RsaPssParams<'a> { reader.read_nested(header.length, |reader| { Ok(Self { hash: reader - .context_specific(TagNumber::N0, TagMode::Explicit)? + .context_specific(TagNumber(0), TagMode::Explicit)? .unwrap_or(SHA_1_AI), mask_gen: reader - .context_specific(TagNumber::N1, TagMode::Explicit)? + .context_specific(TagNumber(1), TagMode::Explicit)? .unwrap_or_else(default_mgf1_sha1), salt_len: reader - .context_specific(TagNumber::N2, TagMode::Explicit)? + .context_specific(TagNumber(2), TagMode::Explicit)? .unwrap_or(RsaPssParams::SALT_LEN_DEFAULT), trailer_field: reader - .context_specific(TagNumber::N3, TagMode::Explicit)? + .context_specific(TagNumber(3), TagMode::Explicit)? .unwrap_or_default(), }) }) @@ -294,27 +289,24 @@ impl<'a> RsaOaepParams<'a> { } } - fn context_specific_hash(&self) -> Option>> { + fn context_specific_hash( + &self, + ) -> Option>> { if self.hash == SHA_1_AI { None } else { - Some(ContextSpecificRef { - tag_number: TagNumber::N0, - tag_mode: TagMode::Explicit, - value: &self.hash, - }) + Some(ContextSpecificExplicitRef { value: &self.hash }) } } fn context_specific_mask_gen( &self, - ) -> Option>>> { + ) -> Option>>> + { if self.mask_gen == default_mgf1_sha1() { None } else { - Some(ContextSpecificRef { - tag_number: TagNumber::N1, - tag_mode: TagMode::Explicit, + Some(ContextSpecificExplicitRef { value: &self.mask_gen, }) } @@ -322,13 +314,11 @@ impl<'a> RsaOaepParams<'a> { fn context_specific_p_source( &self, - ) -> Option>> { + ) -> Option>> { if self.p_source == default_pempty_string() { None } else { - Some(ContextSpecificRef { - tag_number: TagNumber::N2, - tag_mode: TagMode::Explicit, + Some(ContextSpecificExplicitRef { value: &self.p_source, }) } @@ -351,13 +341,13 @@ impl<'a> DecodeValue<'a> for RsaOaepParams<'a> { reader.read_nested(header.length, |reader| { Ok(Self { hash: reader - .context_specific(TagNumber::N0, TagMode::Explicit)? + .context_specific(TagNumber(0), TagMode::Explicit)? .unwrap_or(SHA_1_AI), mask_gen: reader - .context_specific(TagNumber::N1, TagMode::Explicit)? + .context_specific(TagNumber(1), TagMode::Explicit)? .unwrap_or_else(default_mgf1_sha1), p_source: reader - .context_specific(TagNumber::N2, TagMode::Explicit)? + .context_specific(TagNumber(2), TagMode::Explicit)? .unwrap_or_else(default_pempty_string), }) }) diff --git a/pkcs12/src/safe_bag.rs b/pkcs12/src/safe_bag.rs index 333530821..2bd2319fc 100644 --- a/pkcs12/src/safe_bag.rs +++ b/pkcs12/src/safe_bag.rs @@ -64,12 +64,7 @@ impl ::der::EncodeValue for SafeBag { use ::der::Encode as _; [ self.bag_id.encoded_len()?, - ::der::asn1::ContextSpecificRef { - tag_number: ::der::TagNumber::N0, - tag_mode: ::der::TagMode::Explicit, - value: &content, - } - .encoded_len()?, + ::der::asn1::ContextSpecificExplicitRef::<0, _> { value: &content }.encoded_len()?, self.bag_attributes.encoded_len()?, ] .into_iter() @@ -79,12 +74,7 @@ impl ::der::EncodeValue for SafeBag { use ::der::Encode as _; self.bag_id.encode(writer)?; let content = AnyRef::from_der(&self.bag_value)?; - ::der::asn1::ContextSpecificRef { - tag_number: ::der::TagNumber::N0, - tag_mode: ::der::TagMode::Explicit, - value: &content, - } - .encode(writer)?; + ::der::asn1::ContextSpecificExplicitRef::<0, _> { value: &content }.encode(writer)?; self.bag_attributes.encode(writer)?; Ok(()) } diff --git a/pkcs12/tests/cert_tests.rs b/pkcs12/tests/cert_tests.rs index c25f8d390..cf3b255a6 100644 --- a/pkcs12/tests/cert_tests.rs +++ b/pkcs12/tests/cert_tests.rs @@ -4,7 +4,7 @@ use const_oid::db::{ rfc5912::ID_SHA_256, }; use der::{ - asn1::{ContextSpecific, OctetString}, + asn1::{ContextSpecificExplicit, OctetString}, Decode, Encode, }; use hex_literal::hex; @@ -199,8 +199,8 @@ fn decode_sample_pfx() { for cert_bag in cert_bags { match cert_bag.bag_id { pkcs12::PKCS_12_CERT_BAG_OID => { - let cs: der::asn1::ContextSpecific = - ContextSpecific::from_der(&cert_bag.bag_value).unwrap(); + let cs: der::asn1::ContextSpecificExplicit = + ContextSpecificExplicit::from_der(&cert_bag.bag_value).unwrap(); let cb = cs.value; assert_eq!( include_bytes!("examples/cert.der"), @@ -242,8 +242,8 @@ fn decode_sample_pfx() { for safe_bag in safe_bags { match safe_bag.bag_id { pkcs12::PKCS_12_PKCS8_KEY_BAG_OID => { - let cs: ContextSpecific> = - ContextSpecific::from_der(&safe_bag.bag_value).unwrap(); + let cs: ContextSpecificExplicit> = + ContextSpecificExplicit::from_der(&safe_bag.bag_value).unwrap(); let mut ciphertext = cs.value.encrypted_data.as_bytes().to_vec(); let plaintext = cs .value @@ -606,8 +606,8 @@ fn decode_sample_pfx2() { for safe_bag in safe_bags { match safe_bag.bag_id { pkcs12::PKCS_12_CERT_BAG_OID => { - let cs: ContextSpecific = - ContextSpecific::from_der(&safe_bag.bag_value).unwrap(); + let cs: ContextSpecificExplicit = + ContextSpecificExplicit::from_der(&safe_bag.bag_value).unwrap(); assert_eq!( include_bytes!("examples/cert.der"), cs.value.cert_value.as_bytes() @@ -628,8 +628,8 @@ fn decode_sample_pfx2() { for safe_bag in safe_bags { match safe_bag.bag_id { pkcs12::PKCS_12_PKCS8_KEY_BAG_OID => { - let cs: ContextSpecific> = - ContextSpecific::from_der(&safe_bag.bag_value).unwrap(); + let cs: ContextSpecificExplicit> = + ContextSpecificExplicit::from_der(&safe_bag.bag_value).unwrap(); let mut ciphertext = cs.value.encrypted_data.as_bytes().to_vec(); let plaintext = cs .value diff --git a/pkcs8/src/private_key_info.rs b/pkcs8/src/private_key_info.rs index 9d6392e99..51e58a582 100644 --- a/pkcs8/src/private_key_info.rs +++ b/pkcs8/src/private_key_info.rs @@ -3,9 +3,11 @@ use crate::{Error, Result, Version}; use core::fmt; use der::{ - asn1::{AnyRef, BitStringRef, ContextSpecific, OctetStringRef}, - Decode, DecodeValue, Encode, EncodeValue, FixedTag, Header, Length, Reader, Sequence, TagMode, - TagNumber, Writer, + asn1::{ + AnyRef, BitStringRef, ContextSpecificExplicit, ContextSpecificImplicit, OctetStringRef, + }, + Class, Decode, DecodeValue, Encode, EncodeValue, FixedTag, Header, Length, Reader, Sequence, + TagMode, TagNumber, Tagged, Writer, }; use spki::AlgorithmIdentifier; @@ -28,7 +30,10 @@ use der::pem::PemLabel; use subtle::{Choice, ConstantTimeEq}; /// Context-specific tag number for the public key. -const PUBLIC_KEY_TAG: TagNumber = TagNumber::N1; +const PUBLIC_KEY_TAG: u16 = 1; + +/// Context-specific tag number for the public key. +const PUBLIC_KEY_TAG_NUMBER: TagNumber = TagNumber(PUBLIC_KEY_TAG); /// PKCS#8 `PrivateKeyInfo`. /// @@ -174,14 +179,12 @@ where PubKey: BitStringLike, { /// Get a `BIT STRING` representation of the public key, if present. - fn public_key_bit_string(&self) -> Option>> { + fn public_key_bit_string( + &self, + ) -> Option>> { self.public_key.as_ref().map(|pk| { let value = pk.as_bit_string(); - ContextSpecific { - tag_number: PUBLIC_KEY_TAG, - tag_mode: TagMode::Implicit, - value, - } + ContextSpecificImplicit { value } }) } } @@ -200,14 +203,16 @@ where let version = Version::decode(reader)?; let algorithm = reader.decode()?; let private_key = Key::decode(reader)?; + let public_key = - reader.context_specific::(PUBLIC_KEY_TAG, TagMode::Implicit)?; + ContextSpecificImplicit::::decode_skipping(reader)?; + let public_key = public_key.map(|key| key.value); if version.has_public_key() != public_key.is_some() { return Err(reader.error( der::Tag::ContextSpecific { constructed: true, - number: PUBLIC_KEY_TAG, + number: PUBLIC_KEY_TAG_NUMBER, } .value_error() .kind(), @@ -216,7 +221,10 @@ where // Ignore any remaining extension fields while !reader.is_finished() { - reader.decode::>>()?; + let any = reader.decode::>()?; + if any.tag().class() != Class::ContextSpecific { + return Err(reader.error(any.tag().value_error().kind())); + } } Ok(Self { diff --git a/sec1/src/private_key.rs b/sec1/src/private_key.rs index b1c832350..c07ceb350 100644 --- a/sec1/src/private_key.rs +++ b/sec1/src/private_key.rs @@ -5,10 +5,10 @@ //! //! -use crate::{EcParameters, Error, Result}; +use crate::{parameters, EcParameters, Error, Result}; use core::fmt; use der::{ - asn1::{BitStringRef, ContextSpecific, ContextSpecificRef, OctetStringRef}, + asn1::{BitStringRef, ContextSpecificExplicit, ContextSpecificExplicitRef, OctetStringRef}, Decode, DecodeValue, Encode, EncodeValue, Header, Length, Reader, Sequence, Tag, TagMode, TagNumber, Writer, }; @@ -31,10 +31,16 @@ use der::pem::PemLabel; const VERSION: u8 = 1; /// Context-specific tag number for the elliptic curve parameters. -const EC_PARAMETERS_TAG: TagNumber = TagNumber::new(0); +const EC_PARAMETERS_TAG: u16 = 0; + +/// Context-specific tag number for the elliptic curve parameters. +const EC_PARAMETERS_TAG_NUMBER: TagNumber = TagNumber::new(EC_PARAMETERS_TAG); + +/// Context-specific tag number for the public key. +const PUBLIC_KEY_TAG: u16 = 1; /// Context-specific tag number for the public key. -const PUBLIC_KEY_TAG: TagNumber = TagNumber::new(1); +const PUBLIC_KEY_TAG_NUMBER: TagNumber = TagNumber::new(PUBLIC_KEY_TAG); /// SEC1 elliptic curve private key. /// @@ -71,25 +77,19 @@ pub struct EcPrivateKey<'a> { } impl<'a> EcPrivateKey<'a> { - fn context_specific_parameters(&self) -> Option> { - self.parameters.as_ref().map(|params| ContextSpecificRef { - tag_number: EC_PARAMETERS_TAG, - tag_mode: TagMode::Explicit, - value: params, - }) + fn context_specific_parameters( + &self, + ) -> Option> { + self.parameters + .as_ref() + .map(|params| ContextSpecificExplicitRef { value: params }) } fn context_specific_public_key( &self, - ) -> der::Result>>> { + ) -> der::Result>>> { self.public_key - .map(|pk| { - BitStringRef::from_bytes(pk).map(|value| ContextSpecific { - tag_number: PUBLIC_KEY_TAG, - tag_mode: TagMode::Explicit, - value, - }) - }) + .map(|pk| BitStringRef::from_bytes(pk).map(|value| ContextSpecificExplicit { value })) .transpose() } } @@ -104,9 +104,19 @@ impl<'a> DecodeValue<'a> for EcPrivateKey<'a> { } let private_key = OctetStringRef::decode(reader)?.as_bytes(); - let parameters = reader.context_specific(EC_PARAMETERS_TAG, TagMode::Explicit)?; - let public_key = reader - .context_specific::>(PUBLIC_KEY_TAG, TagMode::Explicit)? + + let parameters = + ContextSpecificExplicit::::decode_skipping( + reader, + )?; + let parameters = parameters.map(|p| p.value); + + let public_key = + ContextSpecificExplicit::>::decode_skipping( + reader, + )?; + let public_key = public_key + .map(|key| key.value) .map(|bs| bs.as_bytes().ok_or_else(|| Tag::BitString.value_error())) .transpose()?; diff --git a/x509-cert/tests/certificate.rs b/x509-cert/tests/certificate.rs index 87b001a36..c710b450c 100644 --- a/x509-cert/tests/certificate.rs +++ b/x509-cert/tests/certificate.rs @@ -1,7 +1,9 @@ //! Certificate tests use der::{ - asn1::{BitStringRef, ContextSpecific, ObjectIdentifier, PrintableStringRef, Utf8StringRef}, + asn1::{ + BitStringRef, ContextSpecificExplicit, ObjectIdentifier, PrintableStringRef, Utf8StringRef, + }, Decode, DecodeValue, Encode, FixedTag, Header, Reader, Tag, Tagged, }; use hex_literal::hex; @@ -90,7 +92,7 @@ impl<'a> DecodeValue<'a> for DeferDecodeTbsCertificate<'a> { header: Header, ) -> der::Result> { reader.read_nested(header.length, |reader| { - let version = ContextSpecific::decode_explicit(reader, ::der::TagNumber::N0)? + let version = ContextSpecificExplicit::decode_explicit(reader, ::der::TagNumber(0))? .map(|cs| cs.value) .unwrap_or_else(Default::default);