ssh_key_fork_arti/public/
rsa.rs1use crate::{Error, Mpint, Result};
4use core::hash::{Hash, Hasher};
5use encoding::{CheckedSum, Decode, Encode, Reader, Writer};
6
7#[cfg(feature = "rsa")]
8use {
9 rsa::{pkcs1v15, traits::PublicKeyParts},
10 sha2::{digest::const_oid::AssociatedOid, Digest},
11};
12
13#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
17pub struct RsaPublicKey {
18 pub e: Mpint,
20
21 pub n: Mpint,
23}
24
25impl RsaPublicKey {}
26
27impl Decode for RsaPublicKey {
28 type Error = Error;
29
30 fn decode(reader: &mut impl Reader) -> Result<Self> {
31 let e = Mpint::decode(reader)?;
32 let n = Mpint::decode(reader)?;
33 Ok(Self { e, n })
34 }
35}
36
37impl Encode for RsaPublicKey {
38 fn encoded_len(&self) -> encoding::Result<usize> {
39 [self.e.encoded_len()?, self.n.encoded_len()?].checked_sum()
40 }
41
42 fn encode(&self, writer: &mut impl Writer) -> encoding::Result<()> {
43 self.e.encode(writer)?;
44 self.n.encode(writer)
45 }
46}
47
48impl Hash for RsaPublicKey {
49 #[inline]
50 fn hash<H: Hasher>(&self, state: &mut H) {
51 self.e.as_bytes().hash(state);
52 self.n.as_bytes().hash(state);
53 }
54}
55
56#[cfg(feature = "rsa")]
57impl TryFrom<RsaPublicKey> for rsa::RsaPublicKey {
58 type Error = Error;
59
60 fn try_from(key: RsaPublicKey) -> Result<rsa::RsaPublicKey> {
61 rsa::RsaPublicKey::try_from(&key)
62 }
63}
64
65#[cfg(feature = "rsa")]
66impl TryFrom<&RsaPublicKey> for rsa::RsaPublicKey {
67 type Error = Error;
68
69 fn try_from(key: &RsaPublicKey) -> Result<rsa::RsaPublicKey> {
70 let ret = rsa::RsaPublicKey::new(
71 rsa::BigUint::try_from(&key.n)?,
72 rsa::BigUint::try_from(&key.e)?,
73 )
74 .map_err(|_| Error::Crypto)?;
75
76 Ok(ret)
77 }
78}
79
80#[cfg(feature = "rsa")]
81impl TryFrom<rsa::RsaPublicKey> for RsaPublicKey {
82 type Error = Error;
83
84 fn try_from(key: rsa::RsaPublicKey) -> Result<RsaPublicKey> {
85 RsaPublicKey::try_from(&key)
86 }
87}
88
89#[cfg(feature = "rsa")]
90impl TryFrom<&rsa::RsaPublicKey> for RsaPublicKey {
91 type Error = Error;
92
93 fn try_from(key: &rsa::RsaPublicKey) -> Result<RsaPublicKey> {
94 Ok(RsaPublicKey {
95 e: key.e().try_into()?,
96 n: key.n().try_into()?,
97 })
98 }
99}
100
101#[cfg(feature = "rsa")]
102impl<D> TryFrom<&RsaPublicKey> for pkcs1v15::VerifyingKey<D>
103where
104 D: Digest + AssociatedOid,
105{
106 type Error = Error;
107
108 fn try_from(key: &RsaPublicKey) -> Result<pkcs1v15::VerifyingKey<D>> {
109 Ok(pkcs1v15::VerifyingKey::new(key.try_into()?))
110 }
111}