sos_vault/encoding/
secret.rs

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, 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
26/// Constants for signer kinds.
27mod signer_kind {
28    pub(crate) const SINGLE_PARTY_ECDSA: u8 = 1;
29    pub(crate) const SINGLE_PARTY_ED25519: u8 = 2;
30}
31
32/// Utility for backwards compatible encoding
33/// when the URL for an account/login secret only
34/// supported a single URL.
35///
36/// Initially a single URL was encoded as a string,
37/// when support for multiple URLs was added a Vec<Url>
38/// is encoded to a JSON string.
39#[derive(serde::Serialize, serde::Deserialize)]
40#[serde(untagged)]
41enum WebsiteUrl {
42    One(Url),
43    Many(Vec<Url>),
44}
45
46impl WebsiteUrl {
47    /// Convert to a vector of URLs.
48    pub fn into_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::other(format!(
173                    "unknown signer kind {}",
174                    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::other(format!(
276                    "unknown age version {}",
277                    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::other(format!(
373                    "unknown file content type {}",
374                    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                // NOTE: must write this bool to be backwards
402                // NOTE: compatible from when `url` was Option<Url>
403                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                    // Original encoding was a String Url
629                    match s.parse::<Url>() {
630                        Ok(u) => WebsiteUrl::One(u).into_vec(),
631                        // Newer encoding is JSON to support
632                        // list of Urls
633                        Err(_) => {
634                            let value: WebsiteUrl = serde_json::from_str(&s)?;
635                            value.into_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                // Make sure it's a valid x25519 identity
877                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}