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