1 //! PKCS#1 version identifier. 2 3 use crate::Error; 4 use der::{Decode, Encode, FixedTag, Reader, Tag, Writer}; 5 6 /// Version identifier for PKCS#1 documents as defined in 7 /// [RFC 8017 Appendix 1.2]. 8 /// 9 /// > version is the version number, for compatibility with future 10 /// > revisions of this document. It SHALL be 0 for this version of the 11 /// > document, unless multi-prime is used; in which case, it SHALL be 1. 12 /// 13 /// ```text 14 /// Version ::= INTEGER { two-prime(0), multi(1) } 15 /// (CONSTRAINED BY 16 /// {-- version must be multi if otherPrimeInfos present --}) 17 /// ``` 18 /// 19 /// [RFC 8017 Appendix 1.2]: https://datatracker.ietf.org/doc/html/rfc8017#appendix-A.1.2 20 #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] 21 #[repr(u8)] 22 pub enum Version { 23 /// Denotes a `two-prime` key 24 TwoPrime = 0, 25 26 /// Denotes a `multi` (i.e. multi-prime) key 27 Multi = 1, 28 } 29 30 impl Version { 31 /// Is this a multi-prime RSA key? is_multi(self) -> bool32 pub fn is_multi(self) -> bool { 33 self == Self::Multi 34 } 35 } 36 37 impl From<Version> for u8 { from(version: Version) -> Self38 fn from(version: Version) -> Self { 39 version as u8 40 } 41 } 42 43 impl TryFrom<u8> for Version { 44 type Error = Error; try_from(byte: u8) -> Result<Version, Error>45 fn try_from(byte: u8) -> Result<Version, Error> { 46 match byte { 47 0 => Ok(Version::TwoPrime), 48 1 => Ok(Version::Multi), 49 _ => Err(Error::Version), 50 } 51 } 52 } 53 54 impl<'a> Decode<'a> for Version { decode<R: Reader<'a>>(decoder: &mut R) -> der::Result<Self>55 fn decode<R: Reader<'a>>(decoder: &mut R) -> der::Result<Self> { 56 Version::try_from(u8::decode(decoder)?).map_err(|_| Self::TAG.value_error()) 57 } 58 } 59 60 impl Encode for Version { encoded_len(&self) -> der::Result<der::Length>61 fn encoded_len(&self) -> der::Result<der::Length> { 62 der::Length::ONE.for_tlv() 63 } 64 encode(&self, writer: &mut impl Writer) -> der::Result<()>65 fn encode(&self, writer: &mut impl Writer) -> der::Result<()> { 66 u8::from(*self).encode(writer) 67 } 68 } 69 70 impl FixedTag for Version { 71 const TAG: Tag = Tag::Integer; 72 } 73