1use crate::{
2 ContentEncryptionAlgorithm, EncryptedPrivateKey, Error, Event, ExportableSigner, Id,
3 KeySecurity, LockableSigner, PreEvent, PrivateKey, PublicKey, Signature, Signer, SignerExt,
4};
5use async_trait::async_trait;
6use serde::de::Error as DeError;
7use serde::de::{Deserialize, Deserializer, SeqAccess, Visitor};
8use serde::ser::{Serialize, SerializeSeq, Serializer};
9use std::fmt;
10use std::sync::RwLock;
11
12pub struct KeySigner {
14 public_key: PublicKey,
15 encrypted_private_key: RwLock<EncryptedPrivateKey>,
16 private_key: RwLock<Option<PrivateKey>>,
17}
18
19impl fmt::Debug for KeySigner {
20 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
21 f.debug_struct("KeySigner")
22 .field(
23 "encrypted_private_key",
24 &*self.encrypted_private_key.read().unwrap(),
25 )
26 .field("public_key", &self.public_key)
27 .finish()
28 }
29}
30
31impl KeySigner {
32 pub fn from_locked_parts(epk: EncryptedPrivateKey, pk: PublicKey) -> Self {
34 Self {
35 public_key: pk,
36 encrypted_private_key: RwLock::new(epk),
37 private_key: RwLock::new(None),
38 }
39 }
40
41 pub fn from_private_key(privk: PrivateKey, password: &str, log_n: u8) -> Result<Self, Error> {
43 let epk = privk.export_encrypted(password, log_n)?;
44 Ok(Self {
45 public_key: privk.public_key(),
46 encrypted_private_key: RwLock::new(epk),
47 private_key: RwLock::new(Some(privk)),
48 })
49 }
50
51 pub fn from_encrypted_private_key(epk: EncryptedPrivateKey, pass: &str) -> Result<Self, Error> {
53 let priv_key = epk.decrypt(pass)?;
54 let pub_key = priv_key.public_key();
55 Ok(Self {
56 encrypted_private_key: RwLock::new(epk),
57 public_key: pub_key,
58 private_key: RwLock::new(Some(priv_key)),
59 })
60 }
61
62 pub fn generate(password: &str, log_n: u8) -> Result<Self, Error> {
64 let privk = PrivateKey::generate();
65 let epk = privk.export_encrypted(password, log_n)?;
66 Ok(Self {
67 public_key: privk.public_key(),
68 encrypted_private_key: RwLock::new(epk),
69 private_key: RwLock::new(Some(privk)),
70 })
71 }
72}
73
74#[async_trait]
75impl Signer for KeySigner {
76 fn public_key(&self) -> PublicKey {
77 self.public_key
78 }
79
80 fn encrypted_private_key(&self) -> Option<EncryptedPrivateKey> {
81 Some(self.encrypted_private_key.read().unwrap().clone())
82 }
83
84 async fn sign_event(&self, input: PreEvent) -> Result<Event, Error> {
85 if input.pubkey != self.public_key() {
87 return Err(Error::InvalidPrivateKey);
88 }
89
90 let id = input.hash()?;
92
93 let signature = self.sign_id(id).await?;
95
96 Ok(Event {
97 id,
98 pubkey: input.pubkey,
99 created_at: input.created_at,
100 kind: input.kind,
101 tags: input.tags,
102 content: input.content,
103 sig: signature,
104 })
105 }
106
107 async fn encrypt(
108 &self,
109 other: &PublicKey,
110 plaintext: &str,
111 algo: ContentEncryptionAlgorithm,
112 ) -> Result<String, Error> {
113 match &*self.private_key.read().unwrap() {
114 Some(pk) => pk.encrypt(other, plaintext, algo),
115 None => Err(Error::SignerIsLocked),
116 }
117 }
118
119 async fn decrypt(&self, other: &PublicKey, ciphertext: &str) -> Result<String, Error> {
120 match &*self.private_key.read().unwrap() {
121 Some(pk) => pk.decrypt(other, ciphertext),
122 None => Err(Error::SignerIsLocked),
123 }
124 }
125
126 fn key_security(&self) -> Result<KeySecurity, Error> {
127 match &*self.private_key.read().unwrap() {
128 Some(pk) => Ok(pk.key_security()),
129 None => Err(Error::SignerIsLocked),
130 }
131 }
132}
133
134#[async_trait]
135impl SignerExt for KeySigner {
136 async fn sign_id(&self, id: Id) -> Result<Signature, Error> {
137 let Some(pk) = self.private_key.read().unwrap().clone() else {
138 return Err(Error::SignerIsLocked);
139 };
140 pk.sign_id(id).await
141 }
142
143 async fn sign(&self, message: &[u8]) -> Result<Signature, Error> {
144 let Some(pk) = self.private_key.read().unwrap().clone() else {
145 return Err(Error::SignerIsLocked);
146 };
147 pk.sign(message).await
148 }
149
150 async fn nip44_conversation_key(&self, other: &PublicKey) -> Result<[u8; 32], Error> {
151 let xpub = other.as_xonly_public_key();
152 match &*self.private_key.read().unwrap() {
153 Some(pk) => Ok(nip44::get_conversation_key(pk.as_secret_key(), xpub)),
154 None => Err(Error::SignerIsLocked),
155 }
156 }
157}
158
159impl LockableSigner for KeySigner {
160 fn is_locked(&self) -> bool {
161 self.private_key.read().unwrap().is_none()
162 }
163
164 fn unlock(&self, password: &str) -> Result<(), Error> {
165 if !self.is_locked() {
166 return Ok(());
167 }
168
169 let private_key = self
170 .encrypted_private_key
171 .read()
172 .unwrap()
173 .decrypt(password)?;
174
175 *self.private_key.write().unwrap() = Some(private_key);
176
177 Ok(())
178 }
179
180 fn lock(&self) {
181 *self.private_key.write().unwrap() = None;
182 }
183
184 fn change_passphrase(&self, old: &str, new: &str, log_n: u8) -> Result<(), Error> {
185 let private_key = self.encrypted_private_key.read().unwrap().decrypt(old)?;
186 *self.encrypted_private_key.write().unwrap() = private_key.export_encrypted(new, log_n)?;
187 *self.private_key.write().unwrap() = Some(private_key);
188 Ok(())
189 }
190
191 fn upgrade(&self, pass: &str, log_n: u8) -> Result<(), Error> {
192 let private_key = self.encrypted_private_key.read().unwrap().decrypt(pass)?;
193 *self.encrypted_private_key.write().unwrap() = private_key.export_encrypted(pass, log_n)?;
194 Ok(())
195 }
196}
197
198#[async_trait]
199impl ExportableSigner for KeySigner {
200 async fn export_private_key_in_hex(
201 &self,
202 pass: &str,
203 log_n: u8,
204 ) -> Result<(String, bool), Error> {
205 if let Some(ref mut pk) = *self.private_key.write().unwrap() {
206 let pkcheck = self.encrypted_private_key.read().unwrap().decrypt(pass)?;
208
209 let output = pk.as_hex_string();
211
212 let mut downgraded = false;
214 if pk.key_security() != pkcheck.key_security() {
215 downgraded = true;
216 *self.encrypted_private_key.write().unwrap() = pk.export_encrypted(pass, log_n)?;
217 }
218 Ok((output, downgraded))
219 } else {
220 Err(Error::SignerIsLocked)
221 }
222 }
223
224 async fn export_private_key_in_bech32(
225 &self,
226 pass: &str,
227 log_n: u8,
228 ) -> Result<(String, bool), Error> {
229 if let Some(ref mut pk) = *self.private_key.write().unwrap() {
230 let pkcheck = self.encrypted_private_key.read().unwrap().decrypt(pass)?;
232
233 let output = pk.as_bech32_string();
235
236 let mut downgraded = false;
238 if pk.key_security() != pkcheck.key_security() {
239 downgraded = true;
240 *self.encrypted_private_key.write().unwrap() = pk.export_encrypted(pass, log_n)?;
241 }
242
243 Ok((output, downgraded))
244 } else {
245 Err(Error::SignerIsLocked)
246 }
247 }
248}
249
250impl Serialize for KeySigner {
251 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
252 where
253 S: Serializer,
254 {
255 let mut seq = serializer.serialize_seq(Some(2))?;
256 seq.serialize_element(&self.public_key)?;
257 seq.serialize_element(&*self.encrypted_private_key.read().unwrap())?;
258 seq.end()
259 }
260}
261
262impl<'de> Deserialize<'de> for KeySigner {
263 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
264 where
265 D: Deserializer<'de>,
266 {
267 deserializer.deserialize_seq(KeySignerVisitor)
268 }
269}
270
271struct KeySignerVisitor;
272
273impl<'de> Visitor<'de> for KeySignerVisitor {
274 type Value = KeySigner;
275
276 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
277 write!(f, "a key signer structure as a sequence")
278 }
279
280 fn visit_seq<A>(self, mut access: A) -> Result<KeySigner, A::Error>
281 where
282 A: SeqAccess<'de>,
283 {
284 let public_key = access
285 .next_element::<PublicKey>()?
286 .ok_or_else(|| DeError::custom("Missing or invalid pubkey"))?;
287 let epk = access
288 .next_element::<EncryptedPrivateKey>()?
289 .ok_or_else(|| DeError::custom("Missing or invalid epk"))?;
290
291 Ok(KeySigner {
292 public_key,
293 encrypted_private_key: RwLock::new(epk),
294 private_key: RwLock::new(None),
295 })
296 }
297}
298
299#[cfg(test)]
300mod test {
301 use super::*;
302
303 #[test]
304 fn test_key_signer_serde() {
305 let ks = KeySigner::generate("password", 16).unwrap();
306 let s = serde_json::to_string(&ks).unwrap();
307 println!("{s}");
308 let ks2: KeySigner = serde_json::from_str(&s).unwrap();
309 assert_eq!(ks.public_key, ks2.public_key);
310 assert_eq!(
311 *ks.encrypted_private_key.read().unwrap(),
312 *ks2.encrypted_private_key.read().unwrap()
313 );
314 }
315}