1use 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
15pub type RsaPublicKeyRef<'a> = RsaPublicKey<UintRef<'a>>;
17
18#[cfg(feature = "alloc")]
20pub type RsaPublicKeyOwned = RsaPublicKey<Uint>;
21
22#[derive(Copy, Clone, Debug, Eq, PartialEq)]
35pub struct RsaPublicKey<U> {
36 pub modulus: U,
38
39 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}