1use crate::secret::{
2 AgeVersion, FileContent, IdentityKind, Secret, SecretFlags, SecretMeta,
3 SecretRow, SecretSigner, SecretType, UserData,
4};
5use async_trait::async_trait;
6use binary_stream::futures::{
7 BinaryReader, BinaryWriter, Decodable, Encodable,
8};
9use secrecy::ExposeSecret;
10use sos_core::{
11 encoding::{decode_uuid, encoding_error},
12 UtcDateTime,
13};
14use std::{
15 collections::HashMap,
16 io::{Error, ErrorKind, Result},
17};
18use tokio::io::{AsyncRead, AsyncSeek, AsyncWrite};
19use totp_rs::TOTP;
20use url::Url;
21use vcard4::{self};
22
23const EMBEDDED_FILE: u8 = 1;
24const EXTERNAL_FILE: u8 = 2;
25
26mod signer_kind {
28 pub(crate) const SINGLE_PARTY_ECDSA: u8 = 1;
29 pub(crate) const SINGLE_PARTY_ED25519: u8 = 2;
30}
31
32#[derive(serde::Serialize, serde::Deserialize)]
40#[serde(untagged)]
41enum WebsiteUrl {
42 One(Url),
43 Many(Vec<Url>),
44}
45
46impl WebsiteUrl {
47 pub fn to_vec(self) -> Vec<Url> {
49 match self {
50 Self::One(url) => vec![url],
51 Self::Many(urls) => urls,
52 }
53 }
54}
55
56#[async_trait]
57impl Encodable for SecretMeta {
58 async fn encode<W: AsyncWrite + AsyncSeek + Unpin + Send>(
59 &self,
60 writer: &mut BinaryWriter<W>,
61 ) -> Result<()> {
62 let kind: u8 = self.kind.into();
63 writer.write_u8(kind).await?;
64 writer.write_u32(self.flags.bits()).await?;
65 self.date_created.encode(&mut *writer).await?;
66 self.last_updated.encode(&mut *writer).await?;
67 writer.write_string(&self.label).await?;
68 writer.write_u32(self.tags.len() as u32).await?;
69 for tag in &self.tags {
70 writer.write_string(tag).await?;
71 }
72 writer.write_bool(self.urn.is_some()).await?;
73 if let Some(urn) = &self.urn {
74 writer.write_string(urn).await?;
75 }
76 writer.write_bool(self.owner_id.is_some()).await?;
77 if let Some(owner_id) = &self.owner_id {
78 writer.write_string(owner_id).await?;
79 }
80 writer.write_bool(self.favorite).await?;
81 Ok(())
82 }
83}
84
85#[async_trait]
86impl Decodable for SecretMeta {
87 async fn decode<R: AsyncRead + AsyncSeek + Unpin + Send>(
88 &mut self,
89 reader: &mut BinaryReader<R>,
90 ) -> Result<()> {
91 let kind = reader.read_u8().await?;
92 self.kind = kind.try_into().map_err(encoding_error)?;
93 self.flags = SecretFlags::from_bits(reader.read_u32().await?)
94 .ok_or(crate::Error::InvalidSecretFlags)
95 .map_err(encoding_error)?;
96 let mut date_created: UtcDateTime = Default::default();
97 date_created.decode(&mut *reader).await?;
98 self.date_created = date_created;
99 let mut last_updated: UtcDateTime = Default::default();
100 last_updated.decode(&mut *reader).await?;
101 self.last_updated = last_updated;
102 self.label = reader.read_string().await?;
103 let tag_count = reader.read_u32().await?;
104 for _ in 0..tag_count {
105 let tag = reader.read_string().await?;
106 self.tags.insert(tag);
107 }
108 let has_urn = reader.read_bool().await?;
109 if has_urn {
110 let urn = reader.read_string().await?;
111 self.urn = Some(urn.parse().map_err(encoding_error)?);
112 }
113 let has_owner_id = reader.read_bool().await?;
114 if has_owner_id {
115 let owner_id = reader.read_string().await?;
116 self.owner_id = Some(owner_id.parse().map_err(encoding_error)?);
117 }
118 self.favorite = reader.read_bool().await?;
119 Ok(())
120 }
121}
122
123#[async_trait]
124impl Encodable for SecretSigner {
125 async fn encode<W: AsyncWrite + AsyncSeek + Unpin + Send>(
126 &self,
127 writer: &mut BinaryWriter<W>,
128 ) -> Result<()> {
129 let kind = match self {
130 Self::SinglePartyEcdsa(_) => signer_kind::SINGLE_PARTY_ECDSA,
131 Self::SinglePartyEd25519(_) => signer_kind::SINGLE_PARTY_ED25519,
132 };
133 writer.write_u8(kind).await?;
134
135 match self {
136 Self::SinglePartyEcdsa(buffer)
137 | Self::SinglePartyEd25519(buffer) => {
138 writer
139 .write_u32(buffer.expose_secret().len() as u32)
140 .await?;
141 writer.write_bytes(buffer.expose_secret()).await?;
142 }
143 }
144
145 Ok(())
146 }
147}
148
149#[async_trait]
150impl Decodable for SecretSigner {
151 async fn decode<R: AsyncRead + AsyncSeek + Unpin + Send>(
152 &mut self,
153 reader: &mut BinaryReader<R>,
154 ) -> Result<()> {
155 let kind = reader.read_u8().await?;
156 match kind {
157 signer_kind::SINGLE_PARTY_ECDSA => {
158 let buffer_len = reader.read_u32().await?;
159 let buffer = secrecy::SecretBox::new(
160 reader.read_bytes(buffer_len as usize).await?.into(),
161 );
162 *self = Self::SinglePartyEcdsa(buffer);
163 }
164 signer_kind::SINGLE_PARTY_ED25519 => {
165 let buffer_len = reader.read_u32().await?;
166 let buffer = secrecy::SecretBox::new(
167 reader.read_bytes(buffer_len as usize).await?.into(),
168 );
169 *self = Self::SinglePartyEd25519(buffer);
170 }
171 _ => {
172 return Err(Error::new(
173 ErrorKind::Other,
174 format!("unknown signer kind {}", kind),
175 ));
176 }
177 }
178
179 Ok(())
180 }
181}
182
183#[async_trait]
184impl Encodable for SecretRow {
185 async fn encode<W: AsyncWrite + AsyncSeek + Unpin + Send>(
186 &self,
187 writer: &mut BinaryWriter<W>,
188 ) -> Result<()> {
189 writer.write_bytes(self.id.as_bytes()).await?;
190 self.meta.encode(&mut *writer).await?;
191 self.secret.encode(&mut *writer).await?;
192 Ok(())
193 }
194}
195
196#[async_trait]
197impl Decodable for SecretRow {
198 async fn decode<R: AsyncRead + AsyncSeek + Unpin + Send>(
199 &mut self,
200 reader: &mut BinaryReader<R>,
201 ) -> Result<()> {
202 self.id = decode_uuid(&mut *reader).await?;
203 self.meta.decode(&mut *reader).await?;
204 self.secret.decode(&mut *reader).await?;
205 Ok(())
206 }
207}
208
209async fn write_user_data<W: AsyncWrite + AsyncSeek + Unpin + Send>(
210 user_data: &UserData,
211 writer: &mut BinaryWriter<W>,
212) -> Result<()> {
213 writer.write_u32(user_data.len() as u32).await?;
214 for field in user_data.fields() {
215 field.encode(writer).await?;
216 }
217 writer.write_bool(user_data.comment.is_some()).await?;
218 if let Some(comment) = &user_data.comment {
219 writer.write_string(comment).await?;
220 }
221 writer.write_bool(user_data.recovery_note.is_some()).await?;
222 if let Some(recovery_note) = &user_data.recovery_note {
223 writer.write_string(recovery_note).await?;
224 }
225 Ok(())
226}
227
228async fn read_user_data<R: AsyncRead + AsyncSeek + Unpin + Send>(
229 reader: &mut BinaryReader<R>,
230) -> Result<UserData> {
231 let mut user_data: UserData = Default::default();
232 let count = reader.read_u32().await?;
233
234 for _ in 0..count {
235 let mut field: SecretRow = Default::default();
236 field.decode(reader).await?;
237 user_data.push(field);
238 }
239 let has_comment = reader.read_bool().await?;
240 if has_comment {
241 user_data.comment = Some(reader.read_string().await?);
242 }
243 let has_recovery_note = reader.read_bool().await?;
244 if has_recovery_note {
245 user_data.recovery_note = Some(reader.read_string().await?);
246 }
247 Ok(user_data)
248}
249
250#[async_trait]
251impl Encodable for AgeVersion {
252 async fn encode<W: AsyncWrite + AsyncSeek + Unpin + Send>(
253 &self,
254 writer: &mut BinaryWriter<W>,
255 ) -> Result<()> {
256 match self {
257 Self::Version1 => writer.write_u8(1).await?,
258 };
259 Ok(())
260 }
261}
262
263#[async_trait]
264impl Decodable for AgeVersion {
265 async fn decode<R: AsyncRead + AsyncSeek + Unpin + Send>(
266 &mut self,
267 reader: &mut BinaryReader<R>,
268 ) -> Result<()> {
269 let kind = reader.read_u8().await?;
270 match kind {
271 1 => {
272 *self = Self::Version1;
273 }
274 _ => {
275 return Err(Error::new(
276 ErrorKind::Other,
277 format!("unknown age version {}", kind),
278 ));
279 }
280 };
281 Ok(())
282 }
283}
284
285#[async_trait]
286impl Encodable for FileContent {
287 async fn encode<W: AsyncWrite + AsyncSeek + Unpin + Send>(
288 &self,
289 writer: &mut BinaryWriter<W>,
290 ) -> Result<()> {
291 match self {
292 Self::Embedded {
293 name,
294 mime,
295 buffer,
296 checksum,
297 } => {
298 writer.write_u8(EMBEDDED_FILE).await?;
299 writer.write_string(name).await?;
300 writer.write_string(mime).await?;
301 writer
302 .write_u32(buffer.expose_secret().len() as u32)
303 .await?;
304 writer.write_bytes(buffer.expose_secret()).await?;
305 writer.write_bytes(checksum).await?;
306 }
307 Self::External {
308 name,
309 mime,
310 checksum,
311 size,
312 ..
313 } => {
314 writer.write_u8(EXTERNAL_FILE).await?;
315 writer.write_string(name).await?;
316 writer.write_string(mime).await?;
317 writer.write_bytes(checksum).await?;
318 writer.write_u64(size).await?;
319 }
320 }
321 Ok(())
322 }
323}
324
325#[async_trait]
326impl Decodable for FileContent {
327 async fn decode<R: AsyncRead + AsyncSeek + Unpin + Send>(
328 &mut self,
329 reader: &mut BinaryReader<R>,
330 ) -> Result<()> {
331 let kind = reader.read_u8().await?;
332 match kind {
333 EMBEDDED_FILE => {
334 let name = reader.read_string().await?;
335 let mime = reader.read_string().await?;
336 let buffer_len = reader.read_u32().await?;
337 let buffer = secrecy::SecretBox::new(
338 reader.read_bytes(buffer_len as usize).await?.into(),
339 );
340 let checksum: [u8; 32] = reader
341 .read_bytes(32)
342 .await?
343 .as_slice()
344 .try_into()
345 .map_err(encoding_error)?;
346 *self = Self::Embedded {
347 name,
348 mime,
349 buffer,
350 checksum,
351 };
352 }
353 EXTERNAL_FILE => {
354 let name = reader.read_string().await?;
355 let mime = reader.read_string().await?;
356 let checksum: [u8; 32] = reader
357 .read_bytes(32)
358 .await?
359 .as_slice()
360 .try_into()
361 .map_err(encoding_error)?;
362 let size = reader.read_u64().await?;
363 *self = Self::External {
364 name,
365 mime,
366 checksum,
367 size,
368 path: None,
369 };
370 }
371 _ => {
372 return Err(Error::new(
373 ErrorKind::Other,
374 format!("unknown file content type {}", kind),
375 ));
376 }
377 }
378 Ok(())
379 }
380}
381
382#[async_trait]
383impl Encodable for Secret {
384 async fn encode<W: AsyncWrite + AsyncSeek + Unpin + Send>(
385 &self,
386 writer: &mut BinaryWriter<W>,
387 ) -> Result<()> {
388 let kind: u8 = self.kind().into();
389 writer.write_u8(kind).await?;
390
391 match self {
392 Self::Account {
393 account,
394 password,
395 url,
396 user_data,
397 } => {
398 writer.write_string(account).await?;
399 writer.write_string(password.expose_secret()).await?;
400
401 writer.write_bool(!url.is_empty()).await?;
404 if !url.is_empty() {
405 let websites = WebsiteUrl::Many(url.clone());
406 let value = serde_json::to_string(&websites)?;
407 writer.write_string(value).await?;
408 }
409 write_user_data(user_data, writer).await?;
410 }
411 Self::Note { text, user_data } => {
412 writer.write_string(text.expose_secret()).await?;
413 write_user_data(user_data, writer).await?;
414 }
415 Self::File {
416 content, user_data, ..
417 } => {
418 content.encode(&mut *writer).await?;
419 write_user_data(user_data, writer).await?;
420 }
421 Self::List { items, user_data } => {
422 writer.write_u32(items.len() as u32).await?;
423 for (k, v) in items {
424 writer.write_string(k).await?;
425 writer.write_string(v.expose_secret()).await?;
426 }
427 write_user_data(user_data, writer).await?;
428 }
429 Self::Pem {
430 certificates,
431 user_data,
432 } => {
433 let value = pem::encode_many(certificates);
434 writer.write_string(value).await?;
435 write_user_data(user_data, writer).await?;
436 }
437 Self::Page {
438 title,
439 mime,
440 document,
441 user_data,
442 } => {
443 writer.write_string(title).await?;
444 writer.write_string(mime).await?;
445 writer.write_string(document.expose_secret()).await?;
446 write_user_data(user_data, writer).await?;
447 }
448 Self::Identity {
449 id_kind,
450 number,
451 issue_place,
452 issue_date,
453 expiry_date,
454 user_data,
455 } => {
456 let id_kind: u8 = id_kind.into();
457 writer.write_u8(id_kind).await?;
458 writer.write_string(number.expose_secret()).await?;
459
460 writer.write_bool(issue_place.is_some()).await?;
461 if let Some(issue_place) = issue_place {
462 writer.write_string(issue_place).await?;
463 }
464
465 writer.write_bool(issue_date.is_some()).await?;
466 if let Some(issue_date) = issue_date {
467 issue_date.encode(writer).await?;
468 }
469
470 writer.write_bool(expiry_date.is_some()).await?;
471 if let Some(expiry_date) = expiry_date {
472 expiry_date.encode(writer).await?;
473 }
474
475 write_user_data(user_data, writer).await?;
476 }
477 Self::Signer {
478 private_key,
479 user_data,
480 } => {
481 private_key.encode(writer).await?;
482 write_user_data(user_data, writer).await?;
483 }
484 Self::Contact { vcard, user_data } => {
485 writer.write_string(vcard.to_string()).await?;
486 write_user_data(user_data, writer).await?;
487 }
488 Self::Totp { totp, user_data } => {
489 let totp =
490 serde_json::to_vec(totp).map_err(encoding_error)?;
491 writer.write_u32(totp.len() as u32).await?;
492 writer.write_bytes(totp).await?;
493 write_user_data(user_data, writer).await?;
494 }
495 Self::Card {
496 number,
497 expiry,
498 cvv,
499 name,
500 atm_pin,
501 user_data,
502 } => {
503 writer.write_string(number.expose_secret()).await?;
504
505 writer.write_bool(expiry.is_some()).await?;
506 if let Some(expiry) = expiry {
507 expiry.encode(&mut *writer).await?;
508 }
509 writer.write_string(cvv.expose_secret()).await?;
510
511 writer.write_bool(name.is_some()).await?;
512 if let Some(name) = name {
513 writer.write_string(name.expose_secret()).await?;
514 }
515
516 writer.write_bool(atm_pin.is_some()).await?;
517 if let Some(atm_pin) = atm_pin {
518 writer.write_string(atm_pin.expose_secret()).await?;
519 }
520 write_user_data(user_data, writer).await?;
521 }
522 Self::Bank {
523 number,
524 routing,
525 iban,
526 swift,
527 bic,
528 user_data,
529 } => {
530 writer.write_string(number.expose_secret()).await?;
531 writer.write_string(routing.expose_secret()).await?;
532
533 writer.write_bool(iban.is_some()).await?;
534 if let Some(iban) = iban {
535 writer.write_string(iban.expose_secret()).await?;
536 }
537
538 writer.write_bool(swift.is_some()).await?;
539 if let Some(swift) = swift {
540 writer.write_string(swift.expose_secret()).await?;
541 }
542
543 writer.write_bool(bic.is_some()).await?;
544 if let Some(bic) = bic {
545 writer.write_string(bic.expose_secret()).await?;
546 }
547 write_user_data(user_data, writer).await?;
548 }
549 Self::Link {
550 url,
551 label,
552 title,
553 user_data,
554 } => {
555 writer.write_string(url.expose_secret()).await?;
556
557 writer.write_bool(label.is_some()).await?;
558 if let Some(label) = label {
559 writer.write_string(label.expose_secret()).await?;
560 }
561
562 writer.write_bool(title.is_some()).await?;
563 if let Some(title) = title {
564 writer.write_string(title.expose_secret()).await?;
565 }
566
567 write_user_data(user_data, writer).await?;
568 }
569 Self::Password {
570 password,
571 name,
572 user_data,
573 } => {
574 writer.write_string(password.expose_secret()).await?;
575
576 writer.write_bool(name.is_some()).await?;
577 if let Some(name) = name {
578 writer.write_string(name.expose_secret()).await?;
579 }
580
581 write_user_data(user_data, writer).await?;
582 }
583 Self::Age {
584 version,
585 key,
586 user_data,
587 } => {
588 version.encode(writer).await?;
589 writer.write_string(key.expose_secret()).await?;
590 write_user_data(user_data, writer).await?;
591 }
592 }
593 Ok(())
594 }
595}
596
597#[async_trait]
598impl Decodable for Secret {
599 async fn decode<R: AsyncRead + AsyncSeek + Unpin + Send>(
600 &mut self,
601 reader: &mut BinaryReader<R>,
602 ) -> Result<()> {
603 let kind: SecretType =
604 reader.read_u8().await?.try_into().map_err(encoding_error)?;
605 match kind {
606 SecretType::Note => {
607 let text = reader.read_string().await?;
608 let user_data = read_user_data(reader).await?;
609 *self = Self::Note {
610 text: secrecy::SecretBox::new(text.into()),
611 user_data,
612 };
613 }
614 SecretType::File => {
615 let mut content: FileContent = Default::default();
616 content.decode(&mut *reader).await?;
617 let user_data = read_user_data(reader).await?;
618 *self = Self::File { content, user_data };
619 }
620 SecretType::Account => {
621 let account = reader.read_string().await?;
622 let password = secrecy::SecretBox::new(
623 reader.read_string().await?.into(),
624 );
625 let has_url = reader.read_bool().await?;
626 let url = if has_url {
627 let s = reader.read_string().await?;
628 match s.parse::<Url>() {
630 Ok(u) => WebsiteUrl::One(u).to_vec(),
631 Err(_) => {
634 let value: WebsiteUrl = serde_json::from_str(&s)?;
635 value.to_vec()
636 }
637 }
638 } else {
639 vec![]
640 };
641
642 let user_data = read_user_data(reader).await?;
643
644 *self = Self::Account {
645 account,
646 password,
647 url,
648 user_data,
649 };
650 }
651 SecretType::List => {
652 let items_len = reader.read_u32().await?;
653 let mut items = HashMap::with_capacity(items_len as usize);
654 for _ in 0..items_len {
655 let key = reader.read_string().await?;
656 let value = secrecy::SecretBox::new(
657 reader.read_string().await?.into(),
658 );
659 items.insert(key, value);
660 }
661 let user_data = read_user_data(reader).await?;
662 *self = Self::List { items, user_data };
663 }
664 SecretType::Pem => {
665 let value = reader.read_string().await?;
666 let user_data = read_user_data(reader).await?;
667 *self = Self::Pem {
668 certificates: pem::parse_many(value)
669 .map_err(encoding_error)?,
670
671 user_data,
672 };
673 }
674 SecretType::Page => {
675 let title = reader.read_string().await?;
676 let mime = reader.read_string().await?;
677 let document = secrecy::SecretBox::new(
678 reader.read_string().await?.into(),
679 );
680 let user_data = read_user_data(reader).await?;
681 *self = Self::Page {
682 title,
683 mime,
684 document,
685 user_data,
686 };
687 }
688 SecretType::Identity => {
689 let id_kind = reader.read_u8().await?;
690 let id_kind: IdentityKind =
691 id_kind.try_into().map_err(encoding_error)?;
692
693 let number = reader.read_string().await?.into();
694
695 let has_issue_place = reader.read_bool().await?;
696 let issue_place = if has_issue_place {
697 Some(reader.read_string().await?)
698 } else {
699 None
700 };
701
702 let has_issue_date = reader.read_bool().await?;
703 let issue_date = if has_issue_date {
704 let mut timestamp: UtcDateTime = Default::default();
705 timestamp.decode(&mut *reader).await?;
706 Some(timestamp)
707 } else {
708 None
709 };
710
711 let has_expiry_date = reader.read_bool().await?;
712 let expiry_date = if has_expiry_date {
713 let mut timestamp: UtcDateTime = Default::default();
714 timestamp.decode(&mut *reader).await?;
715 Some(timestamp)
716 } else {
717 None
718 };
719
720 let user_data = read_user_data(reader).await?;
721 *self = Self::Identity {
722 id_kind,
723 number,
724 issue_place,
725 issue_date,
726 expiry_date,
727 user_data,
728 };
729 }
730 SecretType::Signer => {
731 let mut private_key: SecretSigner = Default::default();
732 private_key.decode(reader).await?;
733 let user_data = read_user_data(reader).await?;
734 *self = Self::Signer {
735 private_key,
736 user_data,
737 };
738 }
739 SecretType::Contact => {
740 let vcard = reader.read_string().await?;
741 let mut cards =
742 vcard4::parse(vcard).map_err(encoding_error)?;
743 let vcard = cards.remove(0);
744 let user_data = read_user_data(reader).await?;
745 *self = Self::Contact {
746 vcard: Box::new(vcard),
747 user_data,
748 };
749 }
750 SecretType::Totp => {
751 let buffer_len = reader.read_u32().await?;
752 let buffer = reader.read_bytes(buffer_len as usize).await?;
753 let totp: TOTP = serde_json::from_slice(&buffer)
754 .map_err(encoding_error)?;
755 let user_data = read_user_data(reader).await?;
756 *self = Self::Totp { totp, user_data };
757 }
758 SecretType::Card => {
759 let number = reader.read_string().await?.into();
760 let has_expiry = reader.read_bool().await?;
761 let expiry = if has_expiry {
762 let mut expiry: UtcDateTime = Default::default();
763 expiry.decode(reader).await?;
764 Some(expiry)
765 } else {
766 None
767 };
768 let cvv = reader.read_string().await?.into();
769
770 let has_name = reader.read_bool().await?;
771 let name = if has_name {
772 Some(reader.read_string().await?.into())
773 } else {
774 None
775 };
776
777 let has_atm_pin = reader.read_bool().await?;
778 let atm_pin = if has_atm_pin {
779 Some(reader.read_string().await?.into())
780 } else {
781 None
782 };
783
784 let user_data = read_user_data(reader).await?;
785 *self = Self::Card {
786 number,
787 expiry,
788 cvv,
789 name,
790 atm_pin,
791 user_data,
792 };
793 }
794 SecretType::Bank => {
795 let number = reader.read_string().await?.into();
796 let routing = reader.read_string().await?.into();
797
798 let has_iban = reader.read_bool().await?;
799 let iban = if has_iban {
800 Some(reader.read_string().await?.into())
801 } else {
802 None
803 };
804
805 let has_swift = reader.read_bool().await?;
806 let swift = if has_swift {
807 Some(reader.read_string().await?.into())
808 } else {
809 None
810 };
811
812 let has_bic = reader.read_bool().await?;
813 let bic = if has_bic {
814 Some(reader.read_string().await?.into())
815 } else {
816 None
817 };
818
819 let user_data = read_user_data(reader).await?;
820 *self = Self::Bank {
821 number,
822 routing,
823 iban,
824 swift,
825 bic,
826 user_data,
827 };
828 }
829 SecretType::Link => {
830 let url = reader.read_string().await?.into();
831
832 let has_label = reader.read_bool().await?;
833 let label = if has_label {
834 Some(reader.read_string().await?.into())
835 } else {
836 None
837 };
838
839 let has_title = reader.read_bool().await?;
840 let title = if has_title {
841 Some(reader.read_string().await?.into())
842 } else {
843 None
844 };
845
846 let user_data = read_user_data(reader).await?;
847 *self = Self::Link {
848 url,
849 label,
850 title,
851 user_data,
852 };
853 }
854 SecretType::Password => {
855 let password = reader.read_string().await?.into();
856
857 let has_name = reader.read_bool().await?;
858 let name = if has_name {
859 Some(reader.read_string().await?.into())
860 } else {
861 None
862 };
863
864 let user_data = read_user_data(reader).await?;
865 *self = Self::Password {
866 password,
867 name,
868 user_data,
869 };
870 }
871 SecretType::Age => {
872 let mut version: AgeVersion = Default::default();
873 version.decode(reader).await?;
874 let id = reader.read_string().await?;
875
876 let _: age::x25519::Identity =
878 id.parse().map_err(|s: &str| {
879 encoding_error(crate::Error::InvalidX25519Identity(
880 s.to_string(),
881 ))
882 })?;
883
884 let key = id.into();
885
886 let user_data = read_user_data(reader).await?;
887 *self = Self::Age {
888 version,
889 key,
890 user_data,
891 };
892 }
893 }
894 Ok(())
895 }
896}