redact_crypto/
key.rs

1pub mod ring;
2pub mod sodiumoxide;
3
4use self::{
5    ring::{
6        RingEd25519PublicAsymmetricKey, RingEd25519PublicAsymmetricKeyBuilder,
7        RingEd25519SecretAsymmetricKey, RingEd25519SecretAsymmetricKeyBuilder,
8    },
9    sodiumoxide::{
10        SodiumOxideCurve25519PublicAsymmetricKey, SodiumOxideCurve25519PublicAsymmetricKeyBuilder,
11        SodiumOxideCurve25519SecretAsymmetricKey, SodiumOxideCurve25519SecretAsymmetricKeyBuilder,
12        SodiumOxideEd25519PublicAsymmetricKey, SodiumOxideEd25519PublicAsymmetricKeyBuilder,
13        SodiumOxideEd25519SecretAsymmetricKey, SodiumOxideEd25519SecretAsymmetricKeyBuilder,
14        SodiumOxideSymmetricKey, SodiumOxideSymmetricKeyBuilder,
15    },
16};
17use crate::{
18    Builder, ByteAlgorithm, ByteSource, CryptoError, Entry, HasBuilder, HasByteSource, HasIndex,
19    StorableType, SymmetricNonce, TypeBuilder, TypeBuilderContainer,
20};
21use async_trait::async_trait;
22use futures::Future;
23use mongodb::bson::{self, Document};
24use serde::{Deserialize, Serialize};
25use spki::AlgorithmIdentifier;
26use std::convert::TryFrom;
27
28pub trait Signer {
29    fn sign(&self, bytes: ByteSource) -> Result<ByteSource, CryptoError>;
30}
31
32pub trait Verifier {
33    fn verify(&self, msg: ByteSource, signature: ByteSource) -> Result<(), CryptoError>;
34}
35
36#[async_trait]
37pub trait ToSymmetricByteAlgorithm {
38    type Key: StorableType;
39    type Nonce;
40
41    async fn to_byte_algorithm<F, Fut>(
42        self,
43        nonce: Option<Self::Nonce>,
44        f: F,
45    ) -> Result<ByteAlgorithm, CryptoError>
46    where
47        F: FnOnce(Self::Key) -> Fut + Send,
48        Fut: Future<Output = Result<Entry<Self::Key>, CryptoError>> + Send;
49}
50
51pub trait SymmetricSealer {
52    type SealedOutput;
53    type Nonce;
54
55    fn seal(
56        &self,
57        plaintext: &ByteSource,
58        nonce: Option<&Self::Nonce>,
59    ) -> Result<(Self::SealedOutput, Self::Nonce), CryptoError>;
60}
61
62pub trait SymmetricUnsealer {
63    type UnsealedOutput;
64    type Nonce;
65
66    fn unseal(
67        &self,
68        ciphertext: &ByteSource,
69        nonce: &Self::Nonce,
70    ) -> Result<Self::UnsealedOutput, CryptoError>;
71}
72
73#[async_trait]
74pub trait ToSecretAsymmetricByteAlgorithm {
75    type SecretKey: StorableType;
76    type Nonce;
77    type PublicKey;
78
79    async fn to_byte_algorithm<F, Fut>(
80        self,
81        public_key: Option<Entry<Self::PublicKey>>,
82        nonce: Option<Self::Nonce>,
83        f: F,
84    ) -> Result<ByteAlgorithm, CryptoError>
85    where
86        F: FnOnce(Self::SecretKey) -> Fut + Send,
87        Fut: Future<Output = Result<Entry<Self::SecretKey>, CryptoError>> + Send;
88}
89
90pub trait SecretAsymmetricSealer {
91    type SealedOutput;
92    type Nonce;
93    type PublicKey;
94
95    fn seal(
96        &self,
97        plaintext: &ByteSource,
98        public_key: Option<&Self::PublicKey>,
99        nonce: Option<&Self::Nonce>,
100    ) -> Result<(Self::SealedOutput, Self::Nonce), CryptoError>;
101}
102
103pub trait SecretAsymmetricUnsealer {
104    type UnsealedOutput;
105    type Nonce;
106    type PublicKey;
107
108    fn unseal(
109        &self,
110        ciphertext: &ByteSource,
111        public_key: Option<&Self::PublicKey>,
112        nonce: &Self::Nonce,
113    ) -> Result<Self::UnsealedOutput, CryptoError>;
114}
115
116#[async_trait]
117pub trait ToPublicAsymmetricByteAlgorithm {
118    type SecretKey;
119    type Nonce;
120    type PublicKey: StorableType;
121
122    async fn to_byte_algorithm<F, Fut>(
123        self,
124        secret_key: Entry<Self::SecretKey>,
125        nonce: Option<Self::Nonce>,
126        f: F,
127    ) -> Result<ByteAlgorithm, CryptoError>
128    where
129        F: FnOnce(Self::PublicKey) -> Fut + Send,
130        Fut: Future<Output = Result<Entry<Self::PublicKey>, CryptoError>> + Send;
131}
132
133pub trait PublicAsymmetricSealer {
134    type SealedOutput;
135    type Nonce;
136    type SecretKey;
137
138    fn seal(
139        &self,
140        plaintext: &ByteSource,
141        secret_key: &Self::SecretKey,
142        nonce: Option<&Self::Nonce>,
143    ) -> Result<(Self::SealedOutput, Self::Nonce), CryptoError>;
144}
145
146pub trait PublicAsymmetricUnsealer {
147    type UnsealedOutput;
148    type Nonce;
149    type SecretKey;
150
151    fn unseal(
152        &self,
153        ciphertext: &ByteSource,
154        secret_key: &Self::SecretKey,
155        nonce: &Self::Nonce,
156    ) -> Result<Self::UnsealedOutput, CryptoError>;
157}
158
159pub trait HasPublicKey {
160    type PublicKey: HasByteSource;
161
162    fn public_key(&self) -> Result<Self::PublicKey, CryptoError>;
163}
164
165pub trait HasAlgorithmIdentifier {
166    fn algorithm_identifier<'a>(&self) -> AlgorithmIdentifier<'a>;
167}
168
169#[derive(Debug)]
170pub enum Key {
171    Symmetric(SymmetricKey),
172    Asymmetric(AsymmetricKey),
173}
174
175impl StorableType for Key {}
176
177impl HasIndex for Key {
178    type Index = Document;
179
180    fn get_index() -> Option<Self::Index> {
181        Some(bson::doc! {
182        "c": {
183            "builder": {
184        "t": "Key"
185            }
186        }
187            })
188    }
189}
190
191impl HasBuilder for Key {
192    type Builder = KeyBuilder;
193
194    fn builder(&self) -> Self::Builder {
195        match self {
196            Self::Symmetric(sk) => KeyBuilder::Symmetric(sk.builder()),
197            Self::Asymmetric(ak) => KeyBuilder::Asymmetric(ak.builder()),
198        }
199    }
200}
201
202impl HasByteSource for Key {
203    fn byte_source(&self) -> ByteSource {
204        match self {
205            Self::Symmetric(sk) => sk.byte_source(),
206            Self::Asymmetric(ak) => ak.byte_source(),
207        }
208    }
209}
210
211#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
212#[serde(tag = "t", content = "c")]
213pub enum KeyBuilder {
214    Symmetric(SymmetricKeyBuilder),
215    Asymmetric(AsymmetricKeyBuilder),
216}
217
218impl TryFrom<TypeBuilderContainer> for KeyBuilder {
219    type Error = CryptoError;
220
221    fn try_from(builder: TypeBuilderContainer) -> Result<Self, Self::Error> {
222        match builder.0 {
223            TypeBuilder::Key(kb) => Ok(kb),
224            _ => Err(CryptoError::NotDowncastable),
225        }
226    }
227}
228
229impl From<KeyBuilder> for TypeBuilder {
230    fn from(kb: KeyBuilder) -> TypeBuilder {
231        TypeBuilder::Key(kb)
232    }
233}
234
235impl Builder for KeyBuilder {
236    type Output = Key;
237
238    fn build(&self, bytes: Option<&[u8]>) -> Result<Self::Output, CryptoError> {
239        match self {
240            Self::Symmetric(sk) => Ok(Key::Symmetric(sk.build(bytes)?)),
241            Self::Asymmetric(ak) => Ok(Key::Asymmetric(ak.build(bytes)?)),
242        }
243    }
244}
245
246#[derive(Debug)]
247pub enum SymmetricKey {
248    SodiumOxide(SodiumOxideSymmetricKey),
249}
250
251#[async_trait]
252impl ToSymmetricByteAlgorithm for SymmetricKey {
253    type Key = SymmetricKey;
254    type Nonce = SymmetricNonce;
255
256    async fn to_byte_algorithm<F, Fut>(
257        self,
258        nonce: Option<Self::Nonce>,
259        f: F,
260    ) -> Result<ByteAlgorithm, CryptoError>
261    where
262        F: FnOnce(Self::Key) -> Fut + Send,
263        Fut: Future<Output = Result<Entry<Self::Key>, CryptoError>> + Send,
264    {
265        match self {
266            SymmetricKey::SodiumOxide(sosk) => {
267                let nonce = nonce.map(|n| match n {
268                    SymmetricNonce::SodiumOxide(sosn) => sosn,
269                });
270                sosk.to_byte_algorithm(nonce, |key| async move {
271                    f(SymmetricKey::SodiumOxide(key))
272                        .await?
273                        .cast::<SodiumOxideSymmetricKey>()
274                })
275                .await
276            }
277        }
278    }
279}
280
281impl StorableType for SymmetricKey {}
282
283impl SymmetricSealer for SymmetricKey {
284    type SealedOutput = ByteSource;
285    type Nonce = SymmetricNonce;
286
287    fn seal(
288        &self,
289        plaintext: &ByteSource,
290        nonce: Option<&Self::Nonce>,
291    ) -> Result<(Self::SealedOutput, Self::Nonce), CryptoError> {
292        match self {
293            Self::SodiumOxide(sosk) => {
294                let nonce = nonce.map(|n| match n {
295                    SymmetricNonce::SodiumOxide(sosn) => sosn,
296                });
297                let (output, nonce) = sosk.seal(plaintext, nonce)?;
298                Ok((output, SymmetricNonce::SodiumOxide(nonce)))
299            }
300        }
301    }
302}
303
304impl HasIndex for SymmetricKey {
305    type Index = Document;
306
307    fn get_index() -> Option<Self::Index> {
308        Some(bson::doc! {
309        "c": {
310            "builder": {
311        "t": "Key",
312        "c": {
313            "t": "Symmetric"
314        }
315            }
316        }
317            })
318    }
319}
320
321impl HasBuilder for SymmetricKey {
322    type Builder = SymmetricKeyBuilder;
323
324    fn builder(&self) -> Self::Builder {
325        match self {
326            Self::SodiumOxide(sosk) => SymmetricKeyBuilder::SodiumOxide(sosk.builder()),
327        }
328    }
329}
330
331impl HasByteSource for SymmetricKey {
332    fn byte_source(&self) -> ByteSource {
333        match self {
334            Self::SodiumOxide(sosk) => sosk.byte_source(),
335        }
336    }
337}
338
339#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
340#[serde(tag = "t", content = "c")]
341pub enum SymmetricKeyBuilder {
342    SodiumOxide(SodiumOxideSymmetricKeyBuilder),
343}
344
345impl TryFrom<TypeBuilderContainer> for SymmetricKeyBuilder {
346    type Error = CryptoError;
347
348    fn try_from(builder: TypeBuilderContainer) -> Result<Self, Self::Error> {
349        match builder.0 {
350            TypeBuilder::Key(KeyBuilder::Symmetric(skb)) => Ok(skb),
351            _ => Err(CryptoError::NotDowncastable),
352        }
353    }
354}
355
356impl From<SymmetricKeyBuilder> for TypeBuilder {
357    fn from(skb: SymmetricKeyBuilder) -> TypeBuilder {
358        TypeBuilder::Key(KeyBuilder::Symmetric(skb))
359    }
360}
361
362impl Builder for SymmetricKeyBuilder {
363    type Output = SymmetricKey;
364
365    fn build(&self, bytes: Option<&[u8]>) -> Result<Self::Output, CryptoError> {
366        match self {
367            Self::SodiumOxide(soskb) => Ok(SymmetricKey::SodiumOxide(soskb.build(bytes)?)),
368        }
369    }
370}
371
372#[derive(Debug)]
373pub enum AsymmetricKey {
374    Public(PublicAsymmetricKey),
375    Secret(SecretAsymmetricKey),
376}
377
378impl StorableType for AsymmetricKey {}
379
380impl HasIndex for AsymmetricKey {
381    type Index = Document;
382
383    fn get_index() -> Option<Self::Index> {
384        Some(bson::doc! {
385        "c": {
386            "builder": {
387        "t": "Key",
388        "c": {
389            "t": "Asymmetric",
390        }
391            }
392        }
393            })
394    }
395}
396
397impl HasBuilder for AsymmetricKey {
398    type Builder = AsymmetricKeyBuilder;
399
400    fn builder(&self) -> Self::Builder {
401        match self {
402            Self::Public(pak) => AsymmetricKeyBuilder::Public(pak.builder()),
403            Self::Secret(sak) => AsymmetricKeyBuilder::Secret(sak.builder()),
404        }
405    }
406}
407
408impl HasByteSource for AsymmetricKey {
409    fn byte_source(&self) -> ByteSource {
410        match self {
411            Self::Public(pak) => pak.byte_source(),
412            Self::Secret(sak) => sak.byte_source(),
413        }
414    }
415}
416
417#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
418#[serde(tag = "t", content = "c")]
419pub enum AsymmetricKeyBuilder {
420    Public(PublicAsymmetricKeyBuilder),
421    Secret(SecretAsymmetricKeyBuilder),
422}
423
424impl TryFrom<TypeBuilderContainer> for AsymmetricKeyBuilder {
425    type Error = CryptoError;
426
427    fn try_from(builder: TypeBuilderContainer) -> Result<Self, Self::Error> {
428        match builder.0 {
429            TypeBuilder::Key(KeyBuilder::Asymmetric(akb)) => Ok(akb),
430            _ => Err(CryptoError::NotDowncastable),
431        }
432    }
433}
434
435impl From<AsymmetricKeyBuilder> for TypeBuilder {
436    fn from(akb: AsymmetricKeyBuilder) -> TypeBuilder {
437        TypeBuilder::Key(KeyBuilder::Asymmetric(akb))
438    }
439}
440
441impl Builder for AsymmetricKeyBuilder {
442    type Output = AsymmetricKey;
443
444    fn build(&self, bytes: Option<&[u8]>) -> Result<Self::Output, CryptoError> {
445        match self {
446            Self::Public(pakb) => Ok(AsymmetricKey::Public(pakb.build(bytes)?)),
447            Self::Secret(sakb) => Ok(AsymmetricKey::Secret(sakb.build(bytes)?)),
448        }
449    }
450}
451
452#[derive(Debug)]
453pub enum PublicAsymmetricKey {
454    SodiumOxideCurve25519(SodiumOxideCurve25519PublicAsymmetricKey),
455    SodiumOxideEd25519(SodiumOxideEd25519PublicAsymmetricKey),
456    RingEd25519(RingEd25519PublicAsymmetricKey),
457}
458
459impl StorableType for PublicAsymmetricKey {}
460
461impl HasIndex for PublicAsymmetricKey {
462    type Index = Document;
463
464    fn get_index() -> Option<Self::Index> {
465        Some(bson::doc! {
466        "c": {
467            "builder": {
468        "t": "Key",
469        "c": {
470            "t": "Asymmetric",
471        "c": {
472        "t": "Public"
473        }
474        }
475            }
476        }
477            })
478    }
479}
480
481impl HasBuilder for PublicAsymmetricKey {
482    type Builder = PublicAsymmetricKeyBuilder;
483
484    fn builder(&self) -> Self::Builder {
485        match self {
486            PublicAsymmetricKey::SodiumOxideCurve25519(sopak) => {
487                PublicAsymmetricKeyBuilder::SodiumOxideCurve25519(sopak.builder())
488            }
489            PublicAsymmetricKey::SodiumOxideEd25519(sopak) => {
490                PublicAsymmetricKeyBuilder::SodiumOxideEd25519(sopak.builder())
491            }
492            PublicAsymmetricKey::RingEd25519(rpak) => {
493                PublicAsymmetricKeyBuilder::RingEd25519(rpak.builder())
494            }
495        }
496    }
497}
498
499impl HasByteSource for PublicAsymmetricKey {
500    fn byte_source(&self) -> ByteSource {
501        match self {
502            PublicAsymmetricKey::SodiumOxideCurve25519(sopak) => sopak.byte_source(),
503            PublicAsymmetricKey::SodiumOxideEd25519(sopak) => sopak.byte_source(),
504            PublicAsymmetricKey::RingEd25519(rpak) => rpak.byte_source(),
505        }
506    }
507}
508
509impl HasAlgorithmIdentifier for PublicAsymmetricKey {
510    fn algorithm_identifier<'a>(&self) -> AlgorithmIdentifier<'a> {
511        match self {
512            PublicAsymmetricKey::SodiumOxideCurve25519(k) => k.algorithm_identifier(),
513            PublicAsymmetricKey::SodiumOxideEd25519(k) => k.algorithm_identifier(),
514            PublicAsymmetricKey::RingEd25519(k) => k.algorithm_identifier(),
515        }
516    }
517}
518
519#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
520#[serde(tag = "t", content = "c")]
521pub enum PublicAsymmetricKeyBuilder {
522    SodiumOxideCurve25519(SodiumOxideCurve25519PublicAsymmetricKeyBuilder),
523    SodiumOxideEd25519(SodiumOxideEd25519PublicAsymmetricKeyBuilder),
524    RingEd25519(RingEd25519PublicAsymmetricKeyBuilder),
525}
526
527impl TryFrom<TypeBuilderContainer> for PublicAsymmetricKeyBuilder {
528    type Error = CryptoError;
529
530    fn try_from(builder: TypeBuilderContainer) -> Result<Self, Self::Error> {
531        match builder.0 {
532            TypeBuilder::Key(KeyBuilder::Asymmetric(AsymmetricKeyBuilder::Public(pakb))) => {
533                Ok(pakb)
534            }
535            _ => Err(CryptoError::NotDowncastable),
536        }
537    }
538}
539
540impl From<PublicAsymmetricKeyBuilder> for TypeBuilder {
541    fn from(pakb: PublicAsymmetricKeyBuilder) -> TypeBuilder {
542        TypeBuilder::Key(KeyBuilder::Asymmetric(AsymmetricKeyBuilder::Public(pakb)))
543    }
544}
545
546impl Builder for PublicAsymmetricKeyBuilder {
547    type Output = PublicAsymmetricKey;
548
549    fn build(&self, bytes: Option<&[u8]>) -> Result<Self::Output, CryptoError> {
550        match self {
551            PublicAsymmetricKeyBuilder::SodiumOxideCurve25519(sopakb) => Ok(
552                PublicAsymmetricKey::SodiumOxideCurve25519(sopakb.build(bytes)?),
553            ),
554            PublicAsymmetricKeyBuilder::SodiumOxideEd25519(sopakb) => Ok(
555                PublicAsymmetricKey::SodiumOxideEd25519(sopakb.build(bytes)?),
556            ),
557            PublicAsymmetricKeyBuilder::RingEd25519(rpakb) => {
558                Ok(PublicAsymmetricKey::RingEd25519(rpakb.build(bytes)?))
559            }
560        }
561    }
562}
563
564#[derive(Debug)]
565pub enum SecretAsymmetricKey {
566    SodiumOxideCurve25519(SodiumOxideCurve25519SecretAsymmetricKey),
567    SodiumOxideEd25519(SodiumOxideEd25519SecretAsymmetricKey),
568    RingEd25519(RingEd25519SecretAsymmetricKey),
569}
570
571impl StorableType for SecretAsymmetricKey {}
572
573impl HasIndex for SecretAsymmetricKey {
574    type Index = Document;
575
576    fn get_index() -> Option<Self::Index> {
577        Some(bson::doc! {
578        "c": {
579            "builder": {
580        "t": "Key",
581        "c": {
582            "t": "Asymmetric",
583        "c": {
584        "t": "Secret"
585        }
586        }
587            }
588        }
589            })
590    }
591}
592
593impl HasBuilder for SecretAsymmetricKey {
594    type Builder = SecretAsymmetricKeyBuilder;
595
596    fn builder(&self) -> Self::Builder {
597        match self {
598            SecretAsymmetricKey::SodiumOxideCurve25519(sosak) => {
599                SecretAsymmetricKeyBuilder::SodiumOxideCurve25519(sosak.builder())
600            }
601            SecretAsymmetricKey::SodiumOxideEd25519(sosak) => {
602                SecretAsymmetricKeyBuilder::SodiumOxideEd25519(sosak.builder())
603            }
604            SecretAsymmetricKey::RingEd25519(rsak) => {
605                SecretAsymmetricKeyBuilder::RingEd25519(rsak.builder())
606            }
607        }
608    }
609}
610
611impl HasByteSource for SecretAsymmetricKey {
612    fn byte_source(&self) -> ByteSource {
613        match self {
614            SecretAsymmetricKey::SodiumOxideCurve25519(sosak) => sosak.byte_source(),
615            SecretAsymmetricKey::SodiumOxideEd25519(sosak) => sosak.byte_source(),
616            SecretAsymmetricKey::RingEd25519(rsak) => rsak.byte_source(),
617        }
618    }
619}
620
621#[derive(Debug)]
622pub enum VerifyingKey {
623    SodiumOxideEd25519(SodiumOxideEd25519PublicAsymmetricKey),
624    RingEd25519(RingEd25519PublicAsymmetricKey),
625}
626
627impl StorableType for VerifyingKey {}
628
629impl Verifier for VerifyingKey {
630    fn verify(&self, msg: ByteSource, signature: ByteSource) -> Result<(), CryptoError> {
631        match self {
632            VerifyingKey::SodiumOxideEd25519(k) => k.verify(msg, signature),
633            VerifyingKey::RingEd25519(k) => k.verify(msg, signature),
634        }
635    }
636}
637
638#[derive(Debug)]
639pub enum SigningKey {
640    SodiumOxideEd25519(SodiumOxideEd25519SecretAsymmetricKey),
641    RingEd25519(RingEd25519SecretAsymmetricKey),
642}
643
644impl StorableType for SigningKey {}
645
646#[derive(Debug)]
647pub enum EncryptingKey {
648    SodiumOxideCurve25519(SodiumOxideCurve25519SecretAsymmetricKey),
649    SodiumOxideSymmetricKey(SodiumOxideSymmetricKey),
650}
651
652impl StorableType for EncryptingKey {}
653
654#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
655pub enum SigningKeyBuilder {
656    SodiumOxideEd25519(SodiumOxideEd25519SecretAsymmetricKeyBuilder),
657    RingEd25519(RingEd25519SecretAsymmetricKeyBuilder),
658}
659
660#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
661pub enum EncryptingKeyBuilder {
662    SodiumOxideCurve25519(SodiumOxideCurve25519SecretAsymmetricKeyBuilder),
663    SodiumOxideSymmetricKey(SodiumOxideSymmetricKeyBuilder),
664}
665
666#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
667pub enum VerifyingKeyBuilder {
668    SodiumOxideEd25519(SodiumOxideEd25519PublicAsymmetricKeyBuilder),
669    RingEd25519(RingEd25519PublicAsymmetricKeyBuilder),
670}
671
672impl HasIndex for SigningKey {
673    type Index = Document;
674
675    fn get_index() -> Option<Self::Index> {
676        Some(bson::doc! {
677        "c": {
678            "builder": {
679        "t": "Key",
680        "c": {
681            "t": "Asymmetric",
682        "c": {
683        "t": "Secret"
684        }
685        }
686            }
687        }
688            })
689    }
690}
691
692impl HasIndex for EncryptingKey {
693    type Index = Document;
694
695    fn get_index() -> Option<Self::Index> {
696        Some(bson::doc! {
697        "c": {
698            "builder": {
699                "t": "Key"
700            }
701        }
702            })
703    }
704}
705
706impl HasIndex for VerifyingKey {
707    type Index = Document;
708
709    fn get_index() -> Option<Self::Index> {
710        Some(bson::doc! {
711        "c": {
712            "builder": {
713        "t": "Key",
714        "c": {
715            "t": "Asymmetric",
716        "c": {
717        "t": "Public"
718        }
719        }
720            }
721        }
722            })
723    }
724}
725
726impl HasBuilder for SigningKey {
727    type Builder = SigningKeyBuilder;
728
729    fn builder(&self) -> Self::Builder {
730        match self {
731            SigningKey::SodiumOxideEd25519(sosak) => {
732                SigningKeyBuilder::SodiumOxideEd25519(sosak.builder())
733            }
734            SigningKey::RingEd25519(rsak) => SigningKeyBuilder::RingEd25519(rsak.builder()),
735        }
736    }
737}
738
739impl HasBuilder for EncryptingKey {
740    type Builder = EncryptingKeyBuilder;
741
742    fn builder(&self) -> Self::Builder {
743        match self {
744            EncryptingKey::SodiumOxideCurve25519(sosak) => {
745                EncryptingKeyBuilder::SodiumOxideCurve25519(sosak.builder())
746            }
747            EncryptingKey::SodiumOxideSymmetricKey(ssk) => {
748                EncryptingKeyBuilder::SodiumOxideSymmetricKey(ssk.builder())
749            }
750        }
751    }
752}
753
754impl HasBuilder for VerifyingKey {
755    type Builder = VerifyingKeyBuilder;
756
757    fn builder(&self) -> Self::Builder {
758        match self {
759            VerifyingKey::SodiumOxideEd25519(sopak) => {
760                VerifyingKeyBuilder::SodiumOxideEd25519(sopak.builder())
761            }
762            VerifyingKey::RingEd25519(rpak) => VerifyingKeyBuilder::RingEd25519(rpak.builder()),
763        }
764    }
765}
766
767impl TryFrom<TypeBuilderContainer> for SigningKeyBuilder {
768    type Error = CryptoError;
769
770    fn try_from(builder: TypeBuilderContainer) -> Result<Self, Self::Error> {
771        match builder.0 {
772            TypeBuilder::Key(KeyBuilder::Asymmetric(AsymmetricKeyBuilder::Secret(
773                SecretAsymmetricKeyBuilder::SodiumOxideEd25519(sosak),
774            ))) => Ok(SigningKeyBuilder::SodiumOxideEd25519(sosak)),
775            TypeBuilder::Key(KeyBuilder::Asymmetric(AsymmetricKeyBuilder::Secret(
776                SecretAsymmetricKeyBuilder::RingEd25519(rsak),
777            ))) => Ok(SigningKeyBuilder::RingEd25519(rsak)),
778            _ => Err(CryptoError::NotDowncastable),
779        }
780    }
781}
782
783impl TryFrom<TypeBuilderContainer> for EncryptingKeyBuilder {
784    type Error = CryptoError;
785
786    fn try_from(builder: TypeBuilderContainer) -> Result<Self, Self::Error> {
787        match builder.0 {
788            TypeBuilder::Key(KeyBuilder::Asymmetric(AsymmetricKeyBuilder::Secret(
789                SecretAsymmetricKeyBuilder::SodiumOxideCurve25519(sosak),
790            ))) => Ok(EncryptingKeyBuilder::SodiumOxideCurve25519(sosak)),
791            TypeBuilder::Key(KeyBuilder::Symmetric(SymmetricKeyBuilder::SodiumOxide(ssk))) => {
792                Ok(EncryptingKeyBuilder::SodiumOxideSymmetricKey(ssk))
793            }
794            _ => Err(CryptoError::NotDowncastable),
795        }
796    }
797}
798
799impl TryFrom<TypeBuilderContainer> for VerifyingKeyBuilder {
800    type Error = CryptoError;
801
802    fn try_from(builder: TypeBuilderContainer) -> Result<Self, Self::Error> {
803        match builder.0 {
804            TypeBuilder::Key(KeyBuilder::Asymmetric(AsymmetricKeyBuilder::Public(
805                PublicAsymmetricKeyBuilder::SodiumOxideEd25519(spak),
806            ))) => Ok(VerifyingKeyBuilder::SodiumOxideEd25519(spak)),
807            TypeBuilder::Key(KeyBuilder::Asymmetric(AsymmetricKeyBuilder::Public(
808                PublicAsymmetricKeyBuilder::RingEd25519(rpak),
809            ))) => Ok(VerifyingKeyBuilder::RingEd25519(rpak)),
810            _ => Err(CryptoError::NotDowncastable),
811        }
812    }
813}
814
815impl From<SigningKeyBuilder> for TypeBuilder {
816    fn from(skb: SigningKeyBuilder) -> TypeBuilder {
817        match skb {
818            SigningKeyBuilder::SodiumOxideEd25519(b) => b.into(),
819            SigningKeyBuilder::RingEd25519(b) => b.into(),
820        }
821    }
822}
823
824impl From<EncryptingKeyBuilder> for TypeBuilder {
825    fn from(ekb: EncryptingKeyBuilder) -> TypeBuilder {
826        match ekb {
827            EncryptingKeyBuilder::SodiumOxideCurve25519(b) => b.into(),
828            EncryptingKeyBuilder::SodiumOxideSymmetricKey(b) => b.into(),
829        }
830    }
831}
832
833impl From<VerifyingKeyBuilder> for TypeBuilder {
834    fn from(skb: VerifyingKeyBuilder) -> TypeBuilder {
835        match skb {
836            VerifyingKeyBuilder::SodiumOxideEd25519(b) => b.into(),
837            VerifyingKeyBuilder::RingEd25519(b) => b.into(),
838        }
839    }
840}
841
842impl Builder for SigningKeyBuilder {
843    type Output = SigningKey;
844
845    fn build(&self, bytes: Option<&[u8]>) -> Result<Self::Output, CryptoError> {
846        match self {
847            Self::SodiumOxideEd25519(sk) => Ok(SigningKey::SodiumOxideEd25519(sk.build(bytes)?)),
848            Self::RingEd25519(rk) => Ok(SigningKey::RingEd25519(rk.build(bytes)?)),
849        }
850    }
851}
852
853impl Builder for EncryptingKeyBuilder {
854    type Output = EncryptingKey;
855
856    fn build(&self, bytes: Option<&[u8]>) -> Result<Self::Output, CryptoError> {
857        match self {
858            Self::SodiumOxideCurve25519(sk) => {
859                Ok(EncryptingKey::SodiumOxideCurve25519(sk.build(bytes)?))
860            }
861            Self::SodiumOxideSymmetricKey(sk) => {
862                Ok(EncryptingKey::SodiumOxideSymmetricKey(sk.build(bytes)?))
863            }
864        }
865    }
866}
867
868impl Builder for VerifyingKeyBuilder {
869    type Output = VerifyingKey;
870
871    fn build(&self, bytes: Option<&[u8]>) -> Result<Self::Output, CryptoError> {
872        match self {
873            Self::SodiumOxideEd25519(sk) => Ok(VerifyingKey::SodiumOxideEd25519(sk.build(bytes)?)),
874            Self::RingEd25519(rk) => Ok(VerifyingKey::RingEd25519(rk.build(bytes)?)),
875        }
876    }
877}
878
879impl Signer for SigningKey {
880    fn sign(&self, bytes: ByteSource) -> Result<ByteSource, CryptoError> {
881        match self {
882            SigningKey::SodiumOxideEd25519(k) => k.sign(bytes),
883            SigningKey::RingEd25519(k) => k.sign(bytes),
884        }
885    }
886}
887
888impl Verifier for SigningKey {
889    fn verify(&self, msg: ByteSource, signature: ByteSource) -> Result<(), CryptoError> {
890        match self {
891            SigningKey::SodiumOxideEd25519(k) => k.public_key()?.verify(msg, signature),
892            SigningKey::RingEd25519(k) => k.public_key()?.verify(msg, signature),
893        }
894    }
895}
896
897impl HasAlgorithmIdentifier for SigningKey {
898    fn algorithm_identifier<'a>(&self) -> AlgorithmIdentifier<'a> {
899        match self {
900            SigningKey::SodiumOxideEd25519(k) => k.algorithm_identifier(),
901            SigningKey::RingEd25519(k) => k.algorithm_identifier(),
902        }
903    }
904}
905
906impl HasAlgorithmIdentifier for VerifyingKey {
907    fn algorithm_identifier<'a>(&self) -> AlgorithmIdentifier<'a> {
908        match self {
909            VerifyingKey::SodiumOxideEd25519(k) => k.algorithm_identifier(),
910            VerifyingKey::RingEd25519(k) => k.algorithm_identifier(),
911        }
912    }
913}
914
915impl HasByteSource for SigningKey {
916    fn byte_source(&self) -> ByteSource {
917        match self {
918            SigningKey::SodiumOxideEd25519(k) => k.byte_source(),
919            SigningKey::RingEd25519(k) => k.byte_source(),
920        }
921    }
922}
923
924impl HasByteSource for EncryptingKey {
925    fn byte_source(&self) -> ByteSource {
926        match self {
927            EncryptingKey::SodiumOxideSymmetricKey(k) => k.byte_source(),
928            EncryptingKey::SodiumOxideCurve25519(k) => k.byte_source(),
929        }
930    }
931}
932
933impl HasByteSource for VerifyingKey {
934    fn byte_source(&self) -> ByteSource {
935        match self {
936            VerifyingKey::SodiumOxideEd25519(k) => k.byte_source(),
937            VerifyingKey::RingEd25519(k) => k.byte_source(),
938        }
939    }
940}
941
942impl HasPublicKey for SigningKey {
943    type PublicKey = PublicAsymmetricKey;
944
945    fn public_key(&self) -> Result<Self::PublicKey, CryptoError> {
946        match self {
947            SigningKey::SodiumOxideEd25519(k) => {
948                Ok(PublicAsymmetricKey::SodiumOxideEd25519(k.public_key()?))
949            }
950            SigningKey::RingEd25519(k) => Ok(PublicAsymmetricKey::RingEd25519(k.public_key()?)),
951        }
952    }
953}
954
955#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
956#[serde(tag = "t", content = "c")]
957pub enum SecretAsymmetricKeyBuilder {
958    SodiumOxideCurve25519(SodiumOxideCurve25519SecretAsymmetricKeyBuilder),
959    SodiumOxideEd25519(SodiumOxideEd25519SecretAsymmetricKeyBuilder),
960    RingEd25519(RingEd25519SecretAsymmetricKeyBuilder),
961}
962
963impl TryFrom<TypeBuilderContainer> for SecretAsymmetricKeyBuilder {
964    type Error = CryptoError;
965
966    fn try_from(builder: TypeBuilderContainer) -> Result<Self, Self::Error> {
967        match builder.0 {
968            TypeBuilder::Key(KeyBuilder::Asymmetric(AsymmetricKeyBuilder::Secret(sakb))) => {
969                Ok(sakb)
970            }
971            _ => Err(CryptoError::NotDowncastable),
972        }
973    }
974}
975
976impl From<SecretAsymmetricKeyBuilder> for TypeBuilder {
977    fn from(sakb: SecretAsymmetricKeyBuilder) -> TypeBuilder {
978        TypeBuilder::Key(KeyBuilder::Asymmetric(AsymmetricKeyBuilder::Secret(sakb)))
979    }
980}
981
982impl Builder for SecretAsymmetricKeyBuilder {
983    type Output = SecretAsymmetricKey;
984
985    fn build(&self, bytes: Option<&[u8]>) -> Result<Self::Output, CryptoError> {
986        match self {
987            SecretAsymmetricKeyBuilder::SodiumOxideCurve25519(sosakb) => Ok(
988                SecretAsymmetricKey::SodiumOxideCurve25519(sosakb.build(bytes)?),
989            ),
990            SecretAsymmetricKeyBuilder::SodiumOxideEd25519(sosakb) => Ok(
991                SecretAsymmetricKey::SodiumOxideEd25519(sosakb.build(bytes)?),
992            ),
993            SecretAsymmetricKeyBuilder::RingEd25519(rsakb) => {
994                Ok(SecretAsymmetricKey::RingEd25519(rsakb.build(bytes)?))
995            }
996        }
997    }
998}