1use crate::{public::DsaPublicKey, Error, Mpint, Result};
4use core::fmt;
5use encoding::{CheckedSum, Decode, Encode, Reader, Writer};
6use subtle::{Choice, ConstantTimeEq};
7use zeroize::Zeroize;
8
9#[cfg(all(feature = "dsa", feature = "rand_core"))]
10use rand_core::CryptoRngCore;
11
12#[derive(Clone)]
19pub struct DsaPrivateKey {
20 inner: Mpint,
22}
23
24impl DsaPrivateKey {
25 pub fn as_bytes(&self) -> &[u8] {
27 self.inner.as_bytes()
28 }
29
30 pub fn as_mpint(&self) -> &Mpint {
32 &self.inner
33 }
34}
35
36impl AsRef<[u8]> for DsaPrivateKey {
37 fn as_ref(&self) -> &[u8] {
38 self.as_bytes()
39 }
40}
41
42impl ConstantTimeEq for DsaPrivateKey {
43 fn ct_eq(&self, other: &Self) -> Choice {
44 self.inner.ct_eq(&other.inner)
45 }
46}
47
48impl Eq for DsaPrivateKey {}
49
50impl PartialEq for DsaPrivateKey {
51 fn eq(&self, other: &Self) -> bool {
52 self.ct_eq(other).into()
53 }
54}
55
56impl Decode for DsaPrivateKey {
57 type Error = Error;
58
59 fn decode(reader: &mut impl Reader) -> Result<Self> {
60 Ok(Self {
61 inner: Mpint::decode(reader)?,
62 })
63 }
64}
65
66impl Encode for DsaPrivateKey {
67 fn encoded_len(&self) -> encoding::Result<usize> {
68 self.inner.encoded_len()
69 }
70
71 fn encode(&self, writer: &mut impl Writer) -> encoding::Result<()> {
72 self.inner.encode(writer)
73 }
74}
75
76impl fmt::Debug for DsaPrivateKey {
77 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
78 f.debug_struct("DsaPrivateKey").finish_non_exhaustive()
79 }
80}
81
82impl Drop for DsaPrivateKey {
83 fn drop(&mut self) {
84 self.inner.zeroize();
85 }
86}
87
88#[cfg(feature = "dsa")]
89impl TryFrom<DsaPrivateKey> for dsa::BigUint {
90 type Error = Error;
91
92 fn try_from(key: DsaPrivateKey) -> Result<dsa::BigUint> {
93 dsa::BigUint::try_from(&key.inner)
94 }
95}
96
97#[cfg(feature = "dsa")]
98impl TryFrom<&DsaPrivateKey> for dsa::BigUint {
99 type Error = Error;
100
101 fn try_from(key: &DsaPrivateKey) -> Result<dsa::BigUint> {
102 dsa::BigUint::try_from(&key.inner)
103 }
104}
105
106#[cfg(feature = "dsa")]
107impl TryFrom<dsa::SigningKey> for DsaPrivateKey {
108 type Error = Error;
109
110 fn try_from(key: dsa::SigningKey) -> Result<DsaPrivateKey> {
111 DsaPrivateKey::try_from(&key)
112 }
113}
114
115#[cfg(feature = "dsa")]
116impl TryFrom<&dsa::SigningKey> for DsaPrivateKey {
117 type Error = Error;
118
119 fn try_from(key: &dsa::SigningKey) -> Result<DsaPrivateKey> {
120 Ok(DsaPrivateKey {
121 inner: key.x().try_into()?,
122 })
123 }
124}
125
126#[derive(Clone)]
128pub struct DsaKeypair {
129 pub public: DsaPublicKey,
131
132 pub private: DsaPrivateKey,
134}
135
136impl DsaKeypair {
137 #[cfg(all(feature = "dsa", feature = "rand_core"))]
139 #[allow(deprecated)]
140 pub(crate) const KEY_SIZE: dsa::KeySize = dsa::KeySize::DSA_1024_160;
141
142 #[cfg(all(feature = "dsa", feature = "rand_core"))]
144 pub fn random(rng: &mut impl CryptoRngCore) -> Result<Self> {
145 let components = dsa::Components::generate(rng, Self::KEY_SIZE);
146 dsa::SigningKey::generate(rng, components).try_into()
147 }
148}
149
150impl ConstantTimeEq for DsaKeypair {
151 fn ct_eq(&self, other: &Self) -> Choice {
152 Choice::from((self.public == other.public) as u8) & self.private.ct_eq(&other.private)
153 }
154}
155
156impl PartialEq for DsaKeypair {
157 fn eq(&self, other: &Self) -> bool {
158 self.ct_eq(other).into()
159 }
160}
161
162impl Eq for DsaKeypair {}
163
164impl Decode for DsaKeypair {
165 type Error = Error;
166
167 fn decode(reader: &mut impl Reader) -> Result<Self> {
168 let public = DsaPublicKey::decode(reader)?;
169 let private = DsaPrivateKey::decode(reader)?;
170 Ok(DsaKeypair { public, private })
171 }
172}
173
174impl Encode for DsaKeypair {
175 fn encoded_len(&self) -> encoding::Result<usize> {
176 [self.public.encoded_len()?, self.private.encoded_len()?].checked_sum()
177 }
178
179 fn encode(&self, writer: &mut impl Writer) -> encoding::Result<()> {
180 self.public.encode(writer)?;
181 self.private.encode(writer)
182 }
183}
184
185impl From<DsaKeypair> for DsaPublicKey {
186 fn from(keypair: DsaKeypair) -> DsaPublicKey {
187 keypair.public
188 }
189}
190
191impl From<&DsaKeypair> for DsaPublicKey {
192 fn from(keypair: &DsaKeypair) -> DsaPublicKey {
193 keypair.public.clone()
194 }
195}
196
197impl fmt::Debug for DsaKeypair {
198 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
199 f.debug_struct("DsaKeypair")
200 .field("public", &self.public)
201 .finish_non_exhaustive()
202 }
203}
204
205#[cfg(feature = "dsa")]
206impl TryFrom<DsaKeypair> for dsa::SigningKey {
207 type Error = Error;
208
209 fn try_from(key: DsaKeypair) -> Result<dsa::SigningKey> {
210 dsa::SigningKey::try_from(&key)
211 }
212}
213
214#[cfg(feature = "dsa")]
215impl TryFrom<&DsaKeypair> for dsa::SigningKey {
216 type Error = Error;
217
218 fn try_from(key: &DsaKeypair) -> Result<dsa::SigningKey> {
219 Ok(dsa::SigningKey::from_components(
220 dsa::VerifyingKey::try_from(&key.public)?,
221 dsa::BigUint::try_from(&key.private)?,
222 )?)
223 }
224}
225
226#[cfg(feature = "dsa")]
227impl TryFrom<dsa::SigningKey> for DsaKeypair {
228 type Error = Error;
229
230 fn try_from(key: dsa::SigningKey) -> Result<DsaKeypair> {
231 DsaKeypair::try_from(&key)
232 }
233}
234
235#[cfg(feature = "dsa")]
236impl TryFrom<&dsa::SigningKey> for DsaKeypair {
237 type Error = Error;
238
239 fn try_from(key: &dsa::SigningKey) -> Result<DsaKeypair> {
240 Ok(DsaKeypair {
241 private: key.try_into()?,
242 public: key.verifying_key().try_into()?,
243 })
244 }
245}