1 //! PKCS#1 RSA Public Keys.
2 
3 use crate::{Error, Result};
4 use der::{
5     asn1::UintRef, Decode, DecodeValue, Encode, EncodeValue, Header, Length, Reader, Sequence,
6     Writer,
7 };
8 
9 #[cfg(feature = "alloc")]
10 use der::Document;
11 
12 #[cfg(feature = "pem")]
13 use der::pem::PemLabel;
14 
15 /// PKCS#1 RSA Public Keys as defined in [RFC 8017 Appendix 1.1].
16 ///
17 /// ASN.1 structure containing a serialized RSA public key:
18 ///
19 /// ```text
20 /// RSAPublicKey ::= SEQUENCE {
21 ///     modulus           INTEGER,  -- n
22 ///     publicExponent    INTEGER   -- e
23 /// }
24 /// ```
25 ///
26 /// [RFC 8017 Appendix 1.1]: https://datatracker.ietf.org/doc/html/rfc8017#appendix-A.1.1
27 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
28 pub struct RsaPublicKey<'a> {
29     /// `n`: RSA modulus
30     pub modulus: UintRef<'a>,
31 
32     /// `e`: RSA public exponent
33     pub public_exponent: UintRef<'a>,
34 }
35 
36 impl<'a> DecodeValue<'a> for RsaPublicKey<'a> {
decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> der::Result<Self>37     fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> der::Result<Self> {
38         reader.read_nested(header.length, |reader| {
39             Ok(Self {
40                 modulus: reader.decode()?,
41                 public_exponent: reader.decode()?,
42             })
43         })
44     }
45 }
46 
47 impl EncodeValue for RsaPublicKey<'_> {
value_len(&self) -> der::Result<Length>48     fn value_len(&self) -> der::Result<Length> {
49         self.modulus.encoded_len()? + self.public_exponent.encoded_len()?
50     }
51 
encode_value(&self, writer: &mut impl Writer) -> der::Result<()>52     fn encode_value(&self, writer: &mut impl Writer) -> der::Result<()> {
53         self.modulus.encode(writer)?;
54         self.public_exponent.encode(writer)?;
55         Ok(())
56     }
57 }
58 
59 impl<'a> Sequence<'a> for RsaPublicKey<'a> {}
60 
61 impl<'a> TryFrom<&'a [u8]> for RsaPublicKey<'a> {
62     type Error = Error;
63 
try_from(bytes: &'a [u8]) -> Result<Self>64     fn try_from(bytes: &'a [u8]) -> Result<Self> {
65         Ok(Self::from_der(bytes)?)
66     }
67 }
68 
69 #[cfg(feature = "alloc")]
70 impl TryFrom<RsaPublicKey<'_>> for Document {
71     type Error = Error;
72 
try_from(spki: RsaPublicKey<'_>) -> Result<Document>73     fn try_from(spki: RsaPublicKey<'_>) -> Result<Document> {
74         Self::try_from(&spki)
75     }
76 }
77 
78 #[cfg(feature = "alloc")]
79 impl TryFrom<&RsaPublicKey<'_>> for Document {
80     type Error = Error;
81 
try_from(spki: &RsaPublicKey<'_>) -> Result<Document>82     fn try_from(spki: &RsaPublicKey<'_>) -> Result<Document> {
83         Ok(Self::encode_msg(spki)?)
84     }
85 }
86 
87 #[cfg(feature = "pem")]
88 impl PemLabel for RsaPublicKey<'_> {
89     const PEM_LABEL: &'static str = "RSA PUBLIC KEY";
90 }
91