1use crate::Result;
4
5#[cfg(feature = "alloc")]
6use der::{Document, SecretDocument};
7
8#[cfg(feature = "pem")]
9use {
10 crate::LineEnding,
11 alloc::string::String,
12 der::{pem::PemLabel, zeroize::Zeroizing},
13};
14
15#[cfg(feature = "std")]
16use std::path::Path;
17
18#[cfg(all(feature = "alloc", feature = "pem"))]
19use crate::{RsaPrivateKeyRef, RsaPublicKeyRef};
20
21#[cfg(doc)]
22use crate::{RsaPrivateKey, RsaPublicKey};
23
24pub trait DecodeRsaPrivateKey: Sized {
26 fn from_pkcs1_der(bytes: &[u8]) -> Result<Self>;
29
30 #[cfg(feature = "pem")]
38 fn from_pkcs1_pem(s: &str) -> Result<Self> {
39 let (label, doc) = SecretDocument::from_pem(s)?;
40 RsaPrivateKeyRef::validate_pem_label(label)?;
41 Self::from_pkcs1_der(doc.as_bytes())
42 }
43
44 #[cfg(feature = "std")]
47 fn read_pkcs1_der_file(path: impl AsRef<Path>) -> Result<Self> {
48 Self::from_pkcs1_der(SecretDocument::read_der_file(path)?.as_bytes())
49 }
50
51 #[cfg(all(feature = "pem", feature = "std"))]
53 fn read_pkcs1_pem_file(path: impl AsRef<Path>) -> Result<Self> {
54 let (label, doc) = SecretDocument::read_pem_file(path)?;
55 RsaPrivateKeyRef::validate_pem_label(&label)?;
56 Self::from_pkcs1_der(doc.as_bytes())
57 }
58}
59
60pub trait DecodeRsaPublicKey: Sized {
62 fn from_pkcs1_der(bytes: &[u8]) -> Result<Self>;
65
66 #[cfg(feature = "pem")]
74 fn from_pkcs1_pem(s: &str) -> Result<Self> {
75 let (label, doc) = Document::from_pem(s)?;
76 RsaPublicKeyRef::validate_pem_label(label)?;
77 Self::from_pkcs1_der(doc.as_bytes())
78 }
79
80 #[cfg(feature = "std")]
83 fn read_pkcs1_der_file(path: impl AsRef<Path>) -> Result<Self> {
84 let doc = Document::read_der_file(path)?;
85 Self::from_pkcs1_der(doc.as_bytes())
86 }
87
88 #[cfg(all(feature = "pem", feature = "std"))]
90 fn read_pkcs1_pem_file(path: impl AsRef<Path>) -> Result<Self> {
91 let (label, doc) = Document::read_pem_file(path)?;
92 RsaPublicKeyRef::validate_pem_label(&label)?;
93 Self::from_pkcs1_der(doc.as_bytes())
94 }
95}
96
97#[cfg(feature = "alloc")]
99pub trait EncodeRsaPrivateKey {
100 fn to_pkcs1_der(&self) -> Result<SecretDocument>;
102
103 #[cfg(feature = "pem")]
105 fn to_pkcs1_pem(&self, line_ending: LineEnding) -> Result<Zeroizing<String>> {
106 let doc = self.to_pkcs1_der()?;
107 Ok(doc.to_pem(RsaPrivateKeyRef::PEM_LABEL, line_ending)?)
108 }
109
110 #[cfg(feature = "std")]
112 fn write_pkcs1_der_file(&self, path: impl AsRef<Path>) -> Result<()> {
113 Ok(self.to_pkcs1_der()?.write_der_file(path)?)
114 }
115
116 #[cfg(all(feature = "pem", feature = "std"))]
118 fn write_pkcs1_pem_file(&self, path: impl AsRef<Path>, line_ending: LineEnding) -> Result<()> {
119 let doc = self.to_pkcs1_der()?;
120 Ok(doc.write_pem_file(path, RsaPrivateKeyRef::PEM_LABEL, line_ending)?)
121 }
122}
123
124#[cfg(feature = "alloc")]
126pub trait EncodeRsaPublicKey {
127 fn to_pkcs1_der(&self) -> Result<Document>;
129
130 #[cfg(feature = "pem")]
132 fn to_pkcs1_pem(&self, line_ending: LineEnding) -> Result<String> {
133 let doc = self.to_pkcs1_der()?;
134 Ok(doc.to_pem(RsaPublicKeyRef::PEM_LABEL, line_ending)?)
135 }
136
137 #[cfg(feature = "std")]
139 fn write_pkcs1_der_file(&self, path: impl AsRef<Path>) -> Result<()> {
140 Ok(self.to_pkcs1_der()?.write_der_file(path)?)
141 }
142
143 #[cfg(all(feature = "pem", feature = "std"))]
145 fn write_pkcs1_pem_file(&self, path: impl AsRef<Path>, line_ending: LineEnding) -> Result<()> {
146 let doc = self.to_pkcs1_der()?;
147 Ok(doc.write_pem_file(path, RsaPublicKeyRef::PEM_LABEL, line_ending)?)
148 }
149}