1 //! PKCS#8 version identifier. 2 3 use crate::Error; 4 use der::{Decode, Encode, FixedTag, Reader, Tag, Writer}; 5 6 /// Version identifier for PKCS#8 documents. 7 /// 8 /// (RFC 5958 designates `0` and `1` as the only valid versions for PKCS#8 documents) 9 #[derive(Clone, Debug, Copy, PartialEq, Eq)] 10 pub enum Version { 11 /// Denotes PKCS#8 v1: no public key field. 12 V1 = 0, 13 14 /// Denotes PKCS#8 v2: `OneAsymmetricKey` with public key field. 15 V2 = 1, 16 } 17 18 impl Version { 19 /// Is this version expected to have a public key? has_public_key(self) -> bool20 pub fn has_public_key(self) -> bool { 21 match self { 22 Version::V1 => false, 23 Version::V2 => true, 24 } 25 } 26 } 27 28 impl<'a> Decode<'a> for Version { decode<R: Reader<'a>>(decoder: &mut R) -> der::Result<Self>29 fn decode<R: Reader<'a>>(decoder: &mut R) -> der::Result<Self> { 30 Version::try_from(u8::decode(decoder)?).map_err(|_| Self::TAG.value_error()) 31 } 32 } 33 34 impl Encode for Version { encoded_len(&self) -> der::Result<der::Length>35 fn encoded_len(&self) -> der::Result<der::Length> { 36 der::Length::from(1u8).for_tlv() 37 } 38 encode(&self, writer: &mut impl Writer) -> der::Result<()>39 fn encode(&self, writer: &mut impl Writer) -> der::Result<()> { 40 u8::from(*self).encode(writer) 41 } 42 } 43 44 impl From<Version> for u8 { from(version: Version) -> Self45 fn from(version: Version) -> Self { 46 version as u8 47 } 48 } 49 50 impl TryFrom<u8> for Version { 51 type Error = Error; try_from(byte: u8) -> Result<Version, Error>52 fn try_from(byte: u8) -> Result<Version, Error> { 53 match byte { 54 0 => Ok(Version::V1), 55 1 => Ok(Version::V2), 56 _ => Err(Self::TAG.value_error().into()), 57 } 58 } 59 } 60 61 impl FixedTag for Version { 62 const TAG: Tag = Tag::Integer; 63 } 64