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