Skip to main content

pkcs1/
public_key.rs

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