1use crate::{Error, Result};
4use der::{
5 asn1::UintRef, Decode, DecodeValue, Encode, EncodeValue, Header, Length, Reader, Sequence,
6 Writer,
7};
8
9#[cfg(feature = "alloc")]
10use der::Document;
11
12#[cfg(feature = "pem")]
13use der::pem::PemLabel;
14
15#[derive(Copy, Clone, Debug, Eq, PartialEq)]
28pub struct RsaPublicKey<'a> {
29 pub modulus: UintRef<'a>,
31
32 pub public_exponent: UintRef<'a>,
34}
35
36impl<'a> DecodeValue<'a> for RsaPublicKey<'a> {
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
47impl EncodeValue for RsaPublicKey<'_> {
48 fn value_len(&self) -> der::Result<Length> {
49 self.modulus.encoded_len()? + self.public_exponent.encoded_len()?
50 }
51
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
59impl<'a> Sequence<'a> for RsaPublicKey<'a> {}
60
61impl<'a> TryFrom<&'a [u8]> for RsaPublicKey<'a> {
62 type Error = Error;
63
64 fn try_from(bytes: &'a [u8]) -> Result<Self> {
65 Ok(Self::from_der(bytes)?)
66 }
67}
68
69#[cfg(feature = "alloc")]
70impl TryFrom<RsaPublicKey<'_>> for Document {
71 type Error = Error;
72
73 fn try_from(spki: RsaPublicKey<'_>) -> Result<Document> {
74 Self::try_from(&spki)
75 }
76}
77
78#[cfg(feature = "alloc")]
79impl TryFrom<&RsaPublicKey<'_>> for Document {
80 type Error = Error;
81
82 fn try_from(spki: &RsaPublicKey<'_>) -> Result<Document> {
83 Ok(Self::encode_msg(spki)?)
84 }
85}
86
87#[cfg(feature = "pem")]
88impl PemLabel for RsaPublicKey<'_> {
89 const PEM_LABEL: &'static str = "RSA PUBLIC KEY";
90}