1use crate::Result;
4
5#[cfg(feature = "alloc")]
6use der::SecretDocument;
7#[cfg(feature = "std")]
8use std::path::Path;
9#[cfg(feature = "pem")]
10use {crate::EcPrivateKey, zeroize::Zeroizing};
11#[cfg(feature = "pem")]
12use {crate::LineEnding, alloc::string::String, der::pem::PemLabel};
13
14pub trait DecodeEcPrivateKey: Sized {
16 fn from_sec1_der(bytes: &[u8]) -> Result<Self>;
19
20 #[cfg(feature = "pem")]
28 fn from_sec1_pem(s: &str) -> Result<Self> {
29 let (label, doc) = SecretDocument::from_pem(s)?;
30 EcPrivateKey::validate_pem_label(label)?;
31 Self::from_sec1_der(doc.as_bytes())
32 }
33
34 #[cfg(feature = "std")]
37 fn read_sec1_der_file(path: impl AsRef<Path>) -> Result<Self> {
38 Self::from_sec1_der(SecretDocument::read_der_file(path)?.as_bytes())
39 }
40
41 #[cfg(all(feature = "pem", feature = "std"))]
43 fn read_sec1_pem_file(path: impl AsRef<Path>) -> Result<Self> {
44 let (label, doc) = SecretDocument::read_pem_file(path)?;
45 EcPrivateKey::validate_pem_label(&label)?;
46 Self::from_sec1_der(doc.as_bytes())
47 }
48}
49
50#[cfg(feature = "alloc")]
52pub trait EncodeEcPrivateKey {
53 fn to_sec1_der(&self) -> Result<SecretDocument>;
55
56 #[cfg(feature = "pem")]
60 fn to_sec1_pem(&self, line_ending: LineEnding) -> Result<Zeroizing<String>> {
61 let doc = self.to_sec1_der()?;
62 Ok(doc.to_pem(EcPrivateKey::PEM_LABEL, line_ending)?)
63 }
64
65 #[cfg(feature = "std")]
67 fn write_sec1_der_file(&self, path: impl AsRef<Path>) -> Result<()> {
68 Ok(self.to_sec1_der()?.write_der_file(path)?)
69 }
70
71 #[cfg(all(feature = "pem", feature = "std"))]
73 fn write_sec1_pem_file(&self, path: impl AsRef<Path>, line_ending: LineEnding) -> Result<()> {
74 let doc = self.to_sec1_der()?;
75 Ok(doc.write_pem_file(path, EcPrivateKey::PEM_LABEL, line_ending)?)
76 }
77}