1use crate::{
2 nonce::sodiumoxide::{SodiumOxideAsymmetricNonce, SodiumOxideSymmetricNonce},
3 Algorithm, AsymmetricKeyBuilder, Builder, ByteAlgorithm, ByteSource, CryptoError, Entry,
4 HasBuilder, HasByteSource, HasIndex, HasPublicKey, KeyBuilder, PublicAsymmetricKeyBuilder,
5 PublicAsymmetricSealer, PublicAsymmetricUnsealer, SecretAsymmetricKeyBuilder,
6 SecretAsymmetricSealer, SecretAsymmetricUnsealer, Signer, StorableType, SymmetricKeyBuilder,
7 SymmetricSealer, SymmetricUnsealer, ToPublicAsymmetricByteAlgorithm,
8 ToSecretAsymmetricByteAlgorithm, ToSymmetricByteAlgorithm, TypeBuilder, TypeBuilderContainer,
9 Verifier,
10};
11use async_trait::async_trait;
12use futures::Future;
13use mongodb::bson::{self, Document};
14use serde::{Deserialize, Serialize};
15use sodiumoxide::crypto::{
16 box_::{
17 self,
18 curve25519xsalsa20poly1305::{
19 PublicKey as ExternalSodiumOxideCurve25519PublicAsymmetricKey,
20 SecretKey as ExternalSodiumOxideCurve25519SecretAsymmetricKey,
21 PUBLICKEYBYTES as EXTERNALSODIUMOXIDECURVE25519PUBLICASYMMETRICKEYBYTES,
22 SECRETKEYBYTES as EXTERNALSODIUMOXIDECURVE25519SECRETASYMMETRICKEYBYTES,
23 },
24 },
25 secretbox::{
26 self,
27 xsalsa20poly1305::{
28 Key as ExternalSodiumOxideSymmetricKey,
29 KEYBYTES as EXTERNALSODIUMOXIDESYMMETRICKEYBYTES,
30 },
31 },
32 sign::ed25519::{
33 self, PublicKey as ExternalSodiumOxideEd25519PublicAsymmetricKey,
34 SecretKey as ExternalSodiumOxideEd25519SecretAsymmetricKey, Signature,
35 PUBLICKEYBYTES as EXTERNALSODIUMOXIDEED25519PUBLICASYMMETRICKEYBYTES,
36 SECRETKEYBYTES as EXTERNALSODIUMOXIDEED25519SECRETASYMMETRICKEYBYTES,
37 SEEDBYTES as EXTERNALSODIUMOXIDEED25519SEEDBYTES,
38 },
39 sign::{self, Seed},
40};
41use spki::AlgorithmIdentifier;
42use std::{boxed::Box, convert::TryFrom};
43
44use super::HasAlgorithmIdentifier;
45use sodiumoxide::crypto::sign::Verifier as SodiumOxideVerifier;
46use std::convert::TryInto;
47
48#[derive(Serialize, Deserialize, Debug)]
50pub struct SodiumOxideSymmetricKeyAlgorithm {
51 pub key: Box<Entry<SodiumOxideSymmetricKey>>,
52 pub nonce: SodiumOxideSymmetricNonce,
53}
54
55#[async_trait]
56impl Algorithm for SodiumOxideSymmetricKeyAlgorithm {
57 type Source = ByteSource;
58 type Output = ByteSource;
59
60 async fn unseal(&self, source: &Self::Source) -> Result<Self::Output, CryptoError> {
61 let key = self.key.resolve().await?;
62 Ok(key.unseal(source, &self.nonce)?)
63 }
64
65 async fn seal(&self, source: &Self::Source) -> Result<Self::Output, CryptoError> {
66 let key = self.key.resolve().await?;
67 let (source, _) = key.seal(source, Some(&self.nonce))?;
68 Ok(source)
69 }
70}
71
72#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
73pub struct SodiumOxideSymmetricKeyBuilder {}
74
75impl TryFrom<TypeBuilderContainer> for SodiumOxideSymmetricKeyBuilder {
76 type Error = CryptoError;
77
78 fn try_from(builder: TypeBuilderContainer) -> Result<Self, Self::Error> {
79 match builder.0 {
80 TypeBuilder::Key(KeyBuilder::Symmetric(SymmetricKeyBuilder::SodiumOxide(soskb))) => {
81 Ok(soskb)
82 }
83 _ => Err(CryptoError::NotDowncastable),
84 }
85 }
86}
87
88impl Builder for SodiumOxideSymmetricKeyBuilder {
89 type Output = SodiumOxideSymmetricKey;
90
91 fn build(&self, bytes: Option<&[u8]>) -> Result<Self::Output, CryptoError> {
92 match bytes {
93 Some(bytes) => Ok(SodiumOxideSymmetricKey {
94 key: ExternalSodiumOxideSymmetricKey::from_slice(&bytes).ok_or(
95 CryptoError::InvalidKeyLength {
96 expected: SodiumOxideSymmetricKey::KEYBYTES,
97 actual: bytes.len(),
98 },
99 )?,
100 }),
101 None => Ok(SodiumOxideSymmetricKey::new()),
102 }
103 }
104}
105
106impl From<SodiumOxideSymmetricKeyBuilder> for TypeBuilder {
107 fn from(b: SodiumOxideSymmetricKeyBuilder) -> TypeBuilder {
108 TypeBuilder::Key(KeyBuilder::Symmetric(SymmetricKeyBuilder::SodiumOxide(b)))
109 }
110}
111
112#[derive(Debug)]
113pub struct SodiumOxideSymmetricKey {
114 pub key: ExternalSodiumOxideSymmetricKey,
115}
116
117#[async_trait]
118impl ToSymmetricByteAlgorithm for SodiumOxideSymmetricKey {
119 type Key = Self;
120 type Nonce = SodiumOxideSymmetricNonce;
121
122 async fn to_byte_algorithm<F, Fut>(
123 self,
124 nonce: Option<Self::Nonce>,
125 f: F,
126 ) -> Result<ByteAlgorithm, CryptoError>
127 where
128 F: FnOnce(Self::Key) -> Fut + Send,
129 Fut: Future<Output = Result<Entry<Self::Key>, CryptoError>> + Send,
130 {
131 let nonce = match nonce {
132 Some(nonce) => nonce,
133 None => SodiumOxideSymmetricNonce {
134 nonce: secretbox::gen_nonce(),
135 },
136 };
137 let entry = f(self).await?;
138 Ok(ByteAlgorithm::SodiumOxideSymmetricKey(
139 SodiumOxideSymmetricKeyAlgorithm {
140 key: Box::new(entry),
141 nonce,
142 },
143 ))
144 }
145}
146
147impl StorableType for SodiumOxideSymmetricKey {}
148
149impl SymmetricSealer for SodiumOxideSymmetricKey {
150 type SealedOutput = ByteSource;
151 type Nonce = SodiumOxideSymmetricNonce;
152
153 fn seal(
154 &self,
155 plaintext: &ByteSource,
156 nonce: Option<&Self::Nonce>,
157 ) -> Result<(Self::SealedOutput, Self::Nonce), CryptoError> {
158 let new_nonce = SodiumOxideSymmetricNonce {
159 nonce: secretbox::gen_nonce(),
160 };
161 let nonce = match nonce {
162 Some(n) => n,
163 None => &new_nonce,
164 };
165 let plaintext = plaintext.get()?;
166 let ciphertext = secretbox::seal(plaintext, &nonce.nonce, &self.key);
167 Ok((ciphertext.as_slice().into(), nonce.to_owned()))
168 }
169}
170
171impl SymmetricUnsealer for SodiumOxideSymmetricKey {
172 type UnsealedOutput = ByteSource;
173 type Nonce = SodiumOxideSymmetricNonce;
174
175 fn unseal(
176 &self,
177 ciphertext: &ByteSource,
178 nonce: &Self::Nonce,
179 ) -> Result<Self::UnsealedOutput, CryptoError> {
180 let plaintext = secretbox::open(ciphertext.get()?, &nonce.nonce, &self.key)
181 .map_err(|_| CryptoError::CiphertextFailedVerification)?;
182 Ok(plaintext.as_slice().into())
183 }
184}
185
186impl HasIndex for SodiumOxideSymmetricKey {
187 type Index = Document;
188
189 fn get_index() -> Option<Self::Index> {
190 Some(bson::doc! {
191 "c": {
192 "builder": {
193 "t": "Key",
194 "c": {
195 "t": "Symmetric",
196 "c": {
197 "t": "SodiumOxide"
198 }
199 }
200 }
201 }
202 })
203 }
204}
205
206impl HasBuilder for SodiumOxideSymmetricKey {
207 type Builder = SodiumOxideSymmetricKeyBuilder;
208
209 fn builder(&self) -> Self::Builder {
210 SodiumOxideSymmetricKeyBuilder {}
211 }
212}
213
214impl HasByteSource for SodiumOxideSymmetricKey {
215 fn byte_source(&self) -> ByteSource {
216 self.key.as_ref().into()
217 }
218}
219
220impl SodiumOxideSymmetricKey {
221 pub const KEYBYTES: usize = EXTERNALSODIUMOXIDESYMMETRICKEYBYTES;
222
223 pub fn new() -> Self {
224 SodiumOxideSymmetricKey {
225 key: secretbox::gen_key(),
226 }
227 }
228}
229
230#[derive(Serialize, Deserialize, Debug)]
232pub struct SodiumOxideSecretAsymmetricKeyAlgorithm {
233 pub secret_key: Box<Entry<SodiumOxideCurve25519SecretAsymmetricKey>>,
234 pub nonce: SodiumOxideAsymmetricNonce,
235 pub public_key: Option<Box<Entry<SodiumOxideCurve25519PublicAsymmetricKey>>>,
236}
237
238#[async_trait]
239impl Algorithm for SodiumOxideSecretAsymmetricKeyAlgorithm {
240 type Source = ByteSource;
241 type Output = ByteSource;
242
243 async fn unseal(&self, source: &Self::Source) -> Result<Self::Output, CryptoError> {
244 let secret_key = self.secret_key.resolve().await?;
245 let public_key = match self.public_key {
246 Some(ref public_key) => Ok::<_, CryptoError>(Some(public_key.resolve().await?)),
247 None => Ok(None),
248 }?;
249 Ok(secret_key.unseal(&source, public_key, &self.nonce)?)
250 }
251
252 async fn seal(&self, source: &Self::Source) -> Result<Self::Output, CryptoError> {
253 let secret_key = self.secret_key.resolve().await?;
254 let public_key = match self.public_key {
255 Some(ref public_key) => Ok::<_, CryptoError>(Some(public_key.resolve().await?)),
256 None => Ok(None),
257 }?;
258 let (source, _) = secret_key.seal(&source, public_key, Some(&self.nonce))?;
259 Ok(source)
260 }
261}
262
263#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
264pub struct SodiumOxideCurve25519SecretAsymmetricKeyBuilder {}
265
266impl TryFrom<TypeBuilderContainer> for SodiumOxideCurve25519SecretAsymmetricKeyBuilder {
267 type Error = CryptoError;
268
269 fn try_from(builder: TypeBuilderContainer) -> Result<Self, Self::Error> {
270 match builder.0 {
271 TypeBuilder::Key(KeyBuilder::Asymmetric(AsymmetricKeyBuilder::Secret(
272 SecretAsymmetricKeyBuilder::SodiumOxideCurve25519(sosakb),
273 ))) => Ok(sosakb),
274 _ => Err(CryptoError::NotDowncastable),
275 }
276 }
277}
278
279impl Builder for SodiumOxideCurve25519SecretAsymmetricKeyBuilder {
280 type Output = SodiumOxideCurve25519SecretAsymmetricKey;
281
282 fn build(&self, bytes: Option<&[u8]>) -> Result<Self::Output, CryptoError> {
283 match bytes {
284 Some(bytes) => Ok(SodiumOxideCurve25519SecretAsymmetricKey {
285 secret_key: ExternalSodiumOxideCurve25519SecretAsymmetricKey::from_slice(&bytes)
286 .ok_or(CryptoError::InvalidKeyLength {
287 expected: SodiumOxideCurve25519SecretAsymmetricKey::KEYBYTES,
288 actual: bytes.len(),
289 })?,
290 }),
291 None => Ok(SodiumOxideCurve25519SecretAsymmetricKey::new()),
292 }
293 }
294}
295
296impl From<SodiumOxideCurve25519SecretAsymmetricKeyBuilder> for TypeBuilder {
297 fn from(b: SodiumOxideCurve25519SecretAsymmetricKeyBuilder) -> TypeBuilder {
298 TypeBuilder::Key(KeyBuilder::Asymmetric(AsymmetricKeyBuilder::Secret(
299 SecretAsymmetricKeyBuilder::SodiumOxideCurve25519(b),
300 )))
301 }
302}
303
304#[derive(Debug)]
305pub struct SodiumOxideCurve25519SecretAsymmetricKey {
306 pub secret_key: ExternalSodiumOxideCurve25519SecretAsymmetricKey,
307}
308
309#[async_trait]
310impl ToSecretAsymmetricByteAlgorithm for SodiumOxideCurve25519SecretAsymmetricKey {
311 type SecretKey = Self;
312 type Nonce = SodiumOxideAsymmetricNonce;
313 type PublicKey = SodiumOxideCurve25519PublicAsymmetricKey;
314
315 async fn to_byte_algorithm<F, Fut>(
316 self,
317 public_key: Option<Entry<Self::PublicKey>>,
318 nonce: Option<Self::Nonce>,
319 f: F,
320 ) -> Result<ByteAlgorithm, CryptoError>
321 where
322 F: FnOnce(Self::SecretKey) -> Fut + Send,
323 Fut: Future<Output = Result<Entry<Self::SecretKey>, CryptoError>> + Send,
324 {
325 let nonce = match nonce {
326 Some(nonce) => nonce,
327 None => SodiumOxideAsymmetricNonce {
328 nonce: box_::gen_nonce(),
329 },
330 };
331 let public_key = public_key.map(Box::new);
332 let secret_key = Box::new(f(self).await?);
333 Ok(ByteAlgorithm::SodiumOxideSecretAsymmetricKey(
334 SodiumOxideSecretAsymmetricKeyAlgorithm {
335 secret_key,
336 nonce,
337 public_key,
338 },
339 ))
340 }
341}
342
343impl StorableType for SodiumOxideCurve25519SecretAsymmetricKey {}
344
345impl SecretAsymmetricSealer for SodiumOxideCurve25519SecretAsymmetricKey {
346 type SealedOutput = ByteSource;
347 type Nonce = SodiumOxideAsymmetricNonce;
348 type PublicKey = SodiumOxideCurve25519PublicAsymmetricKey;
349
350 fn seal(
351 &self,
352 plaintext: &ByteSource,
353 public_key: Option<&Self::PublicKey>,
354 nonce: Option<&Self::Nonce>,
355 ) -> Result<(Self::SealedOutput, Self::Nonce), CryptoError> {
356 let new_nonce = SodiumOxideAsymmetricNonce {
357 nonce: box_::gen_nonce(),
358 };
359 let nonce = match nonce {
360 Some(n) => n,
361 None => &new_nonce,
362 };
363 let plaintext = plaintext.get()?;
364 let self_public_key = SodiumOxideCurve25519PublicAsymmetricKey {
365 public_key: self.secret_key.public_key(),
366 };
367 let public_key = match public_key {
368 Some(sopak) => sopak,
369 None => &self_public_key,
370 };
371 let precomputed_key = box_::precompute(&public_key.public_key, &self.secret_key);
372 let ciphertext = box_::seal_precomputed(plaintext, &nonce.nonce, &precomputed_key);
373 Ok((ciphertext.as_slice().into(), nonce.to_owned()))
374 }
375}
376
377impl SecretAsymmetricUnsealer for SodiumOxideCurve25519SecretAsymmetricKey {
378 type UnsealedOutput = ByteSource;
379 type Nonce = SodiumOxideAsymmetricNonce;
380 type PublicKey = SodiumOxideCurve25519PublicAsymmetricKey;
381
382 fn unseal(
383 &self,
384 ciphertext: &ByteSource,
385 public_key: Option<&Self::PublicKey>,
386 nonce: &Self::Nonce,
387 ) -> Result<Self::UnsealedOutput, CryptoError> {
388 let ciphertext = ciphertext.get()?;
389 let self_public_key = SodiumOxideCurve25519PublicAsymmetricKey {
390 public_key: self.secret_key.public_key(),
391 };
392 let public_key = match public_key {
393 Some(sopak) => sopak,
394 None => &self_public_key,
395 };
396 let precomputed_key = box_::precompute(&public_key.public_key, &self.secret_key);
397 let plaintext = box_::open_precomputed(ciphertext, &nonce.nonce, &precomputed_key)
398 .map_err(|_| CryptoError::CiphertextFailedVerification)?;
399 Ok(plaintext.as_slice().into())
400 }
401}
402
403impl HasIndex for SodiumOxideCurve25519SecretAsymmetricKey {
404 type Index = Document;
405
406 fn get_index() -> Option<Self::Index> {
407 Some(bson::doc! {
408 "c": {
409 "builder": {
410 "t": "Key",
411 "c": {
412 "t": "Asymmetric",
413 "c": {
414 "t": "Secret",
415 "c": {
416 "t": "SodiumOxideCurve25519"
417 }
418 }
419 }
420 }
421 }
422 })
423 }
424}
425
426impl HasBuilder for SodiumOxideCurve25519SecretAsymmetricKey {
427 type Builder = SodiumOxideCurve25519SecretAsymmetricKeyBuilder;
428
429 fn builder(&self) -> Self::Builder {
430 SodiumOxideCurve25519SecretAsymmetricKeyBuilder {}
431 }
432}
433
434impl HasByteSource for SodiumOxideCurve25519SecretAsymmetricKey {
435 fn byte_source(&self) -> ByteSource {
436 self.secret_key.as_ref().into()
437 }
438}
439
440impl Default for SodiumOxideCurve25519SecretAsymmetricKey {
441 fn default() -> Self {
442 Self::new()
443 }
444}
445
446impl SodiumOxideCurve25519SecretAsymmetricKey {
447 pub const KEYBYTES: usize = EXTERNALSODIUMOXIDECURVE25519SECRETASYMMETRICKEYBYTES;
448
449 pub fn new() -> Self {
450 let (_, key) = box_::gen_keypair();
451 SodiumOxideCurve25519SecretAsymmetricKey { secret_key: key }
452 }
453
454 pub fn get_signing_key(&self) -> Result<SodiumOxideEd25519SecretAsymmetricKey, CryptoError> {
455 sign::ed25519::Seed::from_slice(&self.secret_key.as_ref())
456 .ok_or(CryptoError::InvalidKeyLength {
457 expected: sign::ed25519::SEEDBYTES,
458 actual: self.secret_key.as_ref().len(),
459 })
460 .map(|seed| {
461 let (_, sk) = sign::ed25519::keypair_from_seed(&seed);
462 SodiumOxideEd25519SecretAsymmetricKey { secret_key: sk }
463 })
464 }
465}
466
467#[derive(Serialize, Deserialize, Debug)]
469pub struct SodiumOxidePublicAsymmetricKeyAlgorithm {
470 pub public_key: Box<Entry<SodiumOxideCurve25519PublicAsymmetricKey>>,
471 pub nonce: SodiumOxideAsymmetricNonce,
472 pub secret_key: Box<Entry<SodiumOxideCurve25519SecretAsymmetricKey>>,
473}
474
475#[async_trait]
476impl Algorithm for SodiumOxidePublicAsymmetricKeyAlgorithm {
477 type Source = ByteSource;
478 type Output = ByteSource;
479
480 async fn unseal(&self, source: &Self::Source) -> Result<Self::Output, CryptoError> {
481 let secret_key = self.secret_key.resolve().await?;
482 let public_key = self.public_key.resolve().await?;
483 Ok(public_key.unseal(source, secret_key, &self.nonce)?)
484 }
485
486 async fn seal(&self, source: &Self::Source) -> Result<Self::Output, CryptoError> {
487 let secret_key = self.secret_key.resolve().await?;
488 let public_key = self.public_key.resolve().await?;
489 let (source, _) = public_key.seal(source, secret_key, Some(&self.nonce))?;
490 Ok(source)
491 }
492}
493
494#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
495pub struct SodiumOxideCurve25519PublicAsymmetricKeyBuilder {}
496
497impl TryFrom<TypeBuilderContainer> for SodiumOxideCurve25519PublicAsymmetricKeyBuilder {
498 type Error = CryptoError;
499
500 fn try_from(builder: TypeBuilderContainer) -> Result<Self, Self::Error> {
501 match builder.0 {
502 TypeBuilder::Key(KeyBuilder::Asymmetric(AsymmetricKeyBuilder::Public(
503 PublicAsymmetricKeyBuilder::SodiumOxideCurve25519(sopakb),
504 ))) => Ok(sopakb),
505 _ => Err(CryptoError::NotDowncastable),
506 }
507 }
508}
509
510impl Builder for SodiumOxideCurve25519PublicAsymmetricKeyBuilder {
511 type Output = SodiumOxideCurve25519PublicAsymmetricKey;
512
513 fn build(&self, bytes: Option<&[u8]>) -> Result<Self::Output, CryptoError> {
514 match bytes {
515 Some(bytes) => Ok(SodiumOxideCurve25519PublicAsymmetricKey {
516 public_key: ExternalSodiumOxideCurve25519PublicAsymmetricKey::from_slice(&bytes)
517 .ok_or(CryptoError::InvalidKeyLength {
518 expected: SodiumOxideCurve25519PublicAsymmetricKey::KEYBYTES,
519 actual: bytes.len(),
520 })?,
521 }),
522 None => {
523 let (pk, _) = SodiumOxideCurve25519PublicAsymmetricKey::new();
524 Ok(pk)
525 }
526 }
527 }
528}
529
530impl From<SodiumOxideCurve25519PublicAsymmetricKeyBuilder> for TypeBuilder {
531 fn from(b: SodiumOxideCurve25519PublicAsymmetricKeyBuilder) -> TypeBuilder {
532 TypeBuilder::Key(KeyBuilder::Asymmetric(AsymmetricKeyBuilder::Public(
533 PublicAsymmetricKeyBuilder::SodiumOxideCurve25519(b),
534 )))
535 }
536}
537
538#[derive(Debug)]
539pub struct SodiumOxideCurve25519PublicAsymmetricKey {
540 pub public_key: ExternalSodiumOxideCurve25519PublicAsymmetricKey,
541}
542
543#[async_trait]
544impl ToPublicAsymmetricByteAlgorithm for SodiumOxideCurve25519PublicAsymmetricKey {
545 type SecretKey = SodiumOxideCurve25519SecretAsymmetricKey;
546 type Nonce = SodiumOxideAsymmetricNonce;
547 type PublicKey = Self;
548
549 async fn to_byte_algorithm<F, Fut>(
550 self,
551 secret_key: Entry<Self::SecretKey>,
552 nonce: Option<Self::Nonce>,
553 f: F,
554 ) -> Result<ByteAlgorithm, CryptoError>
555 where
556 F: FnOnce(Self::PublicKey) -> Fut + Send,
557 Fut: Future<Output = Result<Entry<Self::PublicKey>, CryptoError>> + Send,
558 {
559 let nonce = match nonce {
560 Some(nonce) => nonce,
561 None => SodiumOxideAsymmetricNonce {
562 nonce: box_::gen_nonce(),
563 },
564 };
565 let secret_key = Box::new(secret_key);
566 let public_key = Box::new(f(self).await?);
567 Ok(ByteAlgorithm::SodiumOxidePublicAsymmetricKey(
568 SodiumOxidePublicAsymmetricKeyAlgorithm {
569 secret_key,
570 nonce,
571 public_key,
572 },
573 ))
574 }
575}
576
577impl StorableType for SodiumOxideCurve25519PublicAsymmetricKey {}
578
579impl PublicAsymmetricSealer for SodiumOxideCurve25519PublicAsymmetricKey {
580 type SealedOutput = ByteSource;
581 type Nonce = SodiumOxideAsymmetricNonce;
582 type SecretKey = SodiumOxideCurve25519SecretAsymmetricKey;
583
584 fn seal(
585 &self,
586 plaintext: &ByteSource,
587 secret_key: &Self::SecretKey,
588 nonce: Option<&Self::Nonce>,
589 ) -> Result<(Self::SealedOutput, Self::Nonce), CryptoError> {
590 let new_nonce = SodiumOxideAsymmetricNonce {
591 nonce: box_::gen_nonce(),
592 };
593 let nonce = match nonce {
594 Some(n) => n,
595 None => &new_nonce,
596 };
597 let plaintext = plaintext.get()?;
598 let precomputed_key = box_::precompute(&self.public_key, &secret_key.secret_key);
599 let ciphertext = box_::seal_precomputed(plaintext, &nonce.nonce, &precomputed_key);
600 Ok((ciphertext.as_slice().into(), nonce.to_owned()))
601 }
602}
603
604impl PublicAsymmetricUnsealer for SodiumOxideCurve25519PublicAsymmetricKey {
605 type UnsealedOutput = ByteSource;
606 type Nonce = SodiumOxideAsymmetricNonce;
607 type SecretKey = SodiumOxideCurve25519SecretAsymmetricKey;
608
609 fn unseal(
610 &self,
611 ciphertext: &ByteSource,
612 secret_key: &Self::SecretKey,
613 nonce: &Self::Nonce,
614 ) -> Result<Self::UnsealedOutput, CryptoError> {
615 let ciphertext = ciphertext.get()?;
616 let precomputed_key = box_::precompute(&self.public_key, &secret_key.secret_key);
617 let plaintext = box_::open_precomputed(ciphertext, &nonce.nonce, &precomputed_key)
618 .map_err(|_| CryptoError::CiphertextFailedVerification)?;
619 Ok(plaintext.as_slice().into())
620 }
621}
622
623impl HasIndex for SodiumOxideCurve25519PublicAsymmetricKey {
624 type Index = Document;
625
626 fn get_index() -> Option<Self::Index> {
627 Some(bson::doc! {
628 "c": {
629 "builder": {
630 "t": "Key",
631 "c": {
632 "t": "Asymmetric",
633 "c": {
634 "t": "Public",
635 "c": {
636 "t": "SodiumOxideCurve25519"
637 }
638 }
639 }
640 }
641 }
642 })
643 }
644}
645
646impl HasBuilder for SodiumOxideCurve25519PublicAsymmetricKey {
647 type Builder = SodiumOxideCurve25519PublicAsymmetricKeyBuilder;
648
649 fn builder(&self) -> Self::Builder {
650 SodiumOxideCurve25519PublicAsymmetricKeyBuilder {}
651 }
652}
653
654impl HasByteSource for SodiumOxideCurve25519PublicAsymmetricKey {
655 fn byte_source(&self) -> ByteSource {
656 self.public_key.as_ref().into()
657 }
658}
659
660impl HasAlgorithmIdentifier for SodiumOxideCurve25519PublicAsymmetricKey {
661 fn algorithm_identifier<'a>(&self) -> AlgorithmIdentifier<'a> {
662 AlgorithmIdentifier {
663 oid: spki::ObjectIdentifier::new("1.3.101.110"),
664 parameters: None,
665 }
666 }
667}
668
669impl SodiumOxideCurve25519PublicAsymmetricKey {
670 pub const KEYBYTES: usize = EXTERNALSODIUMOXIDECURVE25519PUBLICASYMMETRICKEYBYTES;
671
672 pub fn new() -> (Self, SodiumOxideCurve25519SecretAsymmetricKey) {
673 let (public_key, secret_key) = box_::gen_keypair();
674 (
675 SodiumOxideCurve25519PublicAsymmetricKey { public_key },
676 SodiumOxideCurve25519SecretAsymmetricKey { secret_key },
677 )
678 }
679}
680
681impl HasPublicKey for SodiumOxideCurve25519SecretAsymmetricKey {
682 type PublicKey = SodiumOxideCurve25519PublicAsymmetricKey;
683
684 fn public_key(&self) -> Result<Self::PublicKey, CryptoError> {
685 Ok(SodiumOxideCurve25519PublicAsymmetricKey {
686 public_key: self.secret_key.public_key(),
687 })
688 }
689}
690
691impl HasAlgorithmIdentifier for SodiumOxideCurve25519SecretAsymmetricKey {
692 fn algorithm_identifier<'a>(&self) -> AlgorithmIdentifier<'a> {
693 AlgorithmIdentifier {
694 oid: spki::ObjectIdentifier::new("1.3.101.110"),
695 parameters: None,
696 }
697 }
698}
699
700#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
702pub struct SodiumOxideEd25519SecretAsymmetricKeyBuilder {}
703
704impl TryFrom<TypeBuilderContainer> for SodiumOxideEd25519SecretAsymmetricKeyBuilder {
705 type Error = CryptoError;
706
707 fn try_from(builder: TypeBuilderContainer) -> Result<Self, Self::Error> {
708 match builder.0 {
709 TypeBuilder::Key(KeyBuilder::Asymmetric(AsymmetricKeyBuilder::Secret(
710 SecretAsymmetricKeyBuilder::SodiumOxideEd25519(sopakb),
711 ))) => Ok(sopakb),
712 _ => Err(CryptoError::NotDowncastable),
713 }
714 }
715}
716
717impl Builder for SodiumOxideEd25519SecretAsymmetricKeyBuilder {
718 type Output = SodiumOxideEd25519SecretAsymmetricKey;
719
720 fn build(&self, bytes: Option<&[u8]>) -> Result<Self::Output, CryptoError> {
721 match bytes {
722 Some(bytes) => {
723 let len = bytes.len();
724 if len == EXTERNALSODIUMOXIDEED25519SEEDBYTES {
725 let seed = Seed::from_slice(bytes).ok_or(CryptoError::InvalidSeedLength {
726 expected: EXTERNALSODIUMOXIDEED25519SEEDBYTES,
727 actual: len,
728 })?;
729 let (_, secret_key) = ed25519::keypair_from_seed(&seed);
730 Ok(SodiumOxideEd25519SecretAsymmetricKey { secret_key })
731 } else {
732 Ok(SodiumOxideEd25519SecretAsymmetricKey {
733 secret_key: ExternalSodiumOxideEd25519SecretAsymmetricKey::from_slice(
734 bytes,
735 )
736 .ok_or(CryptoError::InvalidKeyLength {
737 expected: SodiumOxideEd25519SecretAsymmetricKey::KEYBYTES,
738 actual: bytes.len(),
739 })?,
740 })
741 }
742 }
743 None => {
744 let sk = SodiumOxideEd25519SecretAsymmetricKey::new();
745 Ok(sk)
746 }
747 }
748 }
749}
750
751impl From<SodiumOxideEd25519SecretAsymmetricKeyBuilder> for TypeBuilder {
752 fn from(b: SodiumOxideEd25519SecretAsymmetricKeyBuilder) -> TypeBuilder {
753 TypeBuilder::Key(KeyBuilder::Asymmetric(AsymmetricKeyBuilder::Secret(
754 SecretAsymmetricKeyBuilder::SodiumOxideEd25519(b),
755 )))
756 }
757}
758
759#[derive(Debug)]
760pub struct SodiumOxideEd25519SecretAsymmetricKey {
761 pub secret_key: ExternalSodiumOxideEd25519SecretAsymmetricKey,
762}
763
764impl StorableType for SodiumOxideEd25519SecretAsymmetricKey {}
765
766impl Signer for SodiumOxideEd25519SecretAsymmetricKey {
767 fn sign(&self, bytes: ByteSource) -> Result<ByteSource, CryptoError> {
768 Ok(sign::sign_detached(bytes.get()?, &self.secret_key)
769 .to_bytes()
770 .as_ref()
771 .into())
772 }
773}
774
775impl HasIndex for SodiumOxideEd25519SecretAsymmetricKey {
776 type Index = Document;
777
778 fn get_index() -> Option<Self::Index> {
779 Some(bson::doc! {
780 "c": {
781 "builder": {
782 "t": "Key",
783 "c": {
784 "t": "Asymmetric",
785 "c": {
786 "t": "Secret",
787 "c": {
788 "t": "SodiumOxideEd25519"
789 }
790 }
791 }
792 }
793 }
794 })
795 }
796}
797
798impl HasBuilder for SodiumOxideEd25519SecretAsymmetricKey {
799 type Builder = SodiumOxideEd25519SecretAsymmetricKeyBuilder;
800
801 fn builder(&self) -> Self::Builder {
802 SodiumOxideEd25519SecretAsymmetricKeyBuilder {}
803 }
804}
805
806impl HasByteSource for SodiumOxideEd25519SecretAsymmetricKey {
807 fn byte_source(&self) -> ByteSource {
808 self.secret_key.as_ref().into()
809 }
810}
811
812impl SodiumOxideEd25519SecretAsymmetricKey {
813 pub const KEYBYTES: usize = EXTERNALSODIUMOXIDEED25519SECRETASYMMETRICKEYBYTES;
814
815 pub fn new() -> Self {
816 let (_, secret_key) = sign::gen_keypair();
817 SodiumOxideEd25519SecretAsymmetricKey { secret_key }
818 }
819}
820
821impl Default for SodiumOxideEd25519SecretAsymmetricKey {
822 fn default() -> Self {
823 Self::new()
824 }
825}
826
827#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
829pub struct SodiumOxideEd25519PublicAsymmetricKeyBuilder {}
830
831impl TryFrom<TypeBuilderContainer> for SodiumOxideEd25519PublicAsymmetricKeyBuilder {
832 type Error = CryptoError;
833
834 fn try_from(builder: TypeBuilderContainer) -> Result<Self, Self::Error> {
835 match builder.0 {
836 TypeBuilder::Key(KeyBuilder::Asymmetric(AsymmetricKeyBuilder::Public(
837 PublicAsymmetricKeyBuilder::SodiumOxideEd25519(sopakb),
838 ))) => Ok(sopakb),
839 _ => Err(CryptoError::NotDowncastable),
840 }
841 }
842}
843
844impl Builder for SodiumOxideEd25519PublicAsymmetricKeyBuilder {
845 type Output = SodiumOxideEd25519PublicAsymmetricKey;
846
847 fn build(&self, bytes: Option<&[u8]>) -> Result<Self::Output, CryptoError> {
848 match bytes {
849 Some(bytes) => Ok(SodiumOxideEd25519PublicAsymmetricKey {
850 public_key: ExternalSodiumOxideEd25519PublicAsymmetricKey::from_slice(&bytes)
851 .ok_or(CryptoError::InvalidKeyLength {
852 expected: SodiumOxideEd25519PublicAsymmetricKey::KEYBYTES,
853 actual: bytes.len(),
854 })?,
855 }),
856 None => {
857 let (pk, _) = SodiumOxideEd25519PublicAsymmetricKey::new();
858 Ok(pk)
859 }
860 }
861 }
862}
863
864impl From<SodiumOxideEd25519PublicAsymmetricKeyBuilder> for TypeBuilder {
865 fn from(b: SodiumOxideEd25519PublicAsymmetricKeyBuilder) -> TypeBuilder {
866 TypeBuilder::Key(KeyBuilder::Asymmetric(AsymmetricKeyBuilder::Public(
867 PublicAsymmetricKeyBuilder::SodiumOxideEd25519(b),
868 )))
869 }
870}
871
872#[derive(Debug)]
873pub struct SodiumOxideEd25519PublicAsymmetricKey {
874 pub public_key: ExternalSodiumOxideEd25519PublicAsymmetricKey,
875}
876
877impl Verifier for SodiumOxideEd25519PublicAsymmetricKey {
878 fn verify(&self, msg: ByteSource, signature: ByteSource) -> Result<(), CryptoError> {
879 let signature_arr: [u8; 64] = signature
880 .get()
881 .map_err(|_e| CryptoError::BadSignature)?
882 .try_into()
883 .map_err(|_e| CryptoError::BadSignature)?;
884 self.public_key
885 .verify(
886 msg.get().map_err(|e| CryptoError::InternalError {
887 source: Box::new(e),
888 })?,
889 &Signature::new(signature_arr),
890 )
891 .map_err(|_e| CryptoError::BadSignature)
892 }
893}
894
895impl StorableType for SodiumOxideEd25519PublicAsymmetricKey {}
896
897impl HasIndex for SodiumOxideEd25519PublicAsymmetricKey {
898 type Index = Document;
899
900 fn get_index() -> Option<Self::Index> {
901 Some(bson::doc! {
902 "c": {
903 "builder": {
904 "t": "Key",
905 "c": {
906 "t": "Asymmetric",
907 "c": {
908 "t": "Public",
909 "c": {
910 "t": "SodiumOxideEd25519"
911 }
912 }
913 }
914 }
915 }
916 })
917 }
918}
919
920impl HasBuilder for SodiumOxideEd25519PublicAsymmetricKey {
921 type Builder = SodiumOxideEd25519PublicAsymmetricKeyBuilder;
922
923 fn builder(&self) -> Self::Builder {
924 SodiumOxideEd25519PublicAsymmetricKeyBuilder {}
925 }
926}
927
928impl HasByteSource for SodiumOxideEd25519PublicAsymmetricKey {
929 fn byte_source(&self) -> ByteSource {
930 self.public_key.as_ref().into()
931 }
932}
933
934impl HasAlgorithmIdentifier for SodiumOxideEd25519PublicAsymmetricKey {
935 fn algorithm_identifier<'a>(&self) -> AlgorithmIdentifier<'a> {
936 AlgorithmIdentifier {
937 oid: spki::ObjectIdentifier::new("1.3.101.112"),
938 parameters: None,
939 }
940 }
941}
942
943impl SodiumOxideEd25519PublicAsymmetricKey {
944 pub const KEYBYTES: usize = EXTERNALSODIUMOXIDEED25519PUBLICASYMMETRICKEYBYTES;
945
946 pub fn new() -> (Self, SodiumOxideEd25519SecretAsymmetricKey) {
947 let (public_key, secret_key) = sign::gen_keypair();
948 (
949 SodiumOxideEd25519PublicAsymmetricKey { public_key },
950 SodiumOxideEd25519SecretAsymmetricKey { secret_key },
951 )
952 }
953}
954
955impl HasPublicKey for SodiumOxideEd25519SecretAsymmetricKey {
956 type PublicKey = SodiumOxideEd25519PublicAsymmetricKey;
957
958 fn public_key(&self) -> Result<Self::PublicKey, CryptoError> {
959 Ok(SodiumOxideEd25519PublicAsymmetricKey {
960 public_key: self.secret_key.public_key(),
961 })
962 }
963}
964
965impl HasAlgorithmIdentifier for SodiumOxideEd25519SecretAsymmetricKey {
966 fn algorithm_identifier<'a>(&self) -> AlgorithmIdentifier<'a> {
967 AlgorithmIdentifier {
968 oid: spki::ObjectIdentifier::new("1.3.101.112"),
969 parameters: None,
970 }
971 }
972}
973
974#[cfg(test)]
975mod tests {
976 use super::{
977 SodiumOxideCurve25519PublicAsymmetricKey, SodiumOxideCurve25519PublicAsymmetricKeyBuilder,
978 SodiumOxideCurve25519SecretAsymmetricKey, SodiumOxideCurve25519SecretAsymmetricKeyBuilder,
979 SodiumOxideSymmetricKey, SodiumOxideSymmetricKeyBuilder,
980 };
981 use crate::key::sodiumoxide::{
982 SodiumOxideEd25519PublicAsymmetricKey, SodiumOxideEd25519PublicAsymmetricKeyBuilder,
983 };
984 use crate::{
985 nonce::sodiumoxide::{SodiumOxideAsymmetricNonce, SodiumOxideSymmetricNonce},
986 storage::tests::MockIndexedStorer,
987 storage::tests::MockStorer,
988 Algorithm, AsymmetricKeyBuilder, BoolDataBuilder, Builder, ByteSource, CryptoError, Data,
989 DataBuilder, HasBuilder, HasByteSource, HasIndex, HasPublicKey, KeyBuilder,
990 PublicAsymmetricKeyBuilder, PublicAsymmetricSealer, PublicAsymmetricUnsealer,
991 SecretAsymmetricKeyBuilder, SecretAsymmetricSealer, SecretAsymmetricUnsealer,
992 SymmetricKeyBuilder, SymmetricSealer, SymmetricUnsealer, ToEntry, ToSymmetricByteAlgorithm,
993 TypeBuilder, TypeBuilderContainer, VectorByteSource, Verifier,
994 };
995 use mongodb::bson;
996 use sodiumoxide::crypto::{
997 box_,
998 secretbox::{self, xsalsa20poly1305::Nonce as ExternalSodiumOxideSymmetricNonce},
999 sign,
1000 };
1001 use std::convert::TryInto;
1002
1003 fn get_sopak_ciphertext(
1007 plaintext: &[u8],
1008 secret_key: Option<&SodiumOxideCurve25519SecretAsymmetricKey>,
1009 ) -> Vec<u8> {
1010 let new_key = get_sosak();
1011 let secret_key = match secret_key {
1012 Some(sk) => sk,
1013 None => &new_key,
1014 };
1015 let (public_key, _) = get_sopak();
1016 let nonce = get_soan();
1017 let precomputed_key = box_::precompute(&public_key.public_key, &secret_key.secret_key);
1018 box_::seal_precomputed(plaintext, &nonce.nonce, &precomputed_key)
1019 }
1020
1021 fn get_sopak() -> (
1022 SodiumOxideCurve25519PublicAsymmetricKey,
1023 SodiumOxideCurve25519SecretAsymmetricKey,
1024 ) {
1025 let key_bytes: [u8; 32] = [
1026 77, 166, 178, 227, 216, 254, 219, 202, 41, 198, 74, 141, 126, 196, 68, 179, 19, 218,
1027 34, 107, 174, 121, 199, 180, 254, 254, 161, 219, 225, 158, 220, 56,
1028 ];
1029 let sosakb = SodiumOxideCurve25519SecretAsymmetricKeyBuilder {};
1030 let secret_key = sosakb.build(Some(&key_bytes)).unwrap();
1031 let public_key = SodiumOxideCurve25519PublicAsymmetricKey {
1032 public_key: secret_key.secret_key.public_key(),
1033 };
1034
1035 (public_key, secret_key)
1036 }
1037
1038 fn get_sosak_ciphertext(
1084 plaintext: &[u8],
1085 public_key: &Option<SodiumOxideCurve25519PublicAsymmetricKey>,
1086 ) -> Vec<u8> {
1087 let key = get_sosak();
1088 let nonce = get_soan();
1089 let own_key = SodiumOxideCurve25519PublicAsymmetricKey {
1090 public_key: key.secret_key.public_key(),
1091 };
1092 let public_key = match public_key {
1093 Some(k) => k,
1094 None => &own_key,
1095 };
1096 let precomputed_key = box_::precompute(&public_key.public_key, &key.secret_key);
1097 box_::seal_precomputed(plaintext, &nonce.nonce, &precomputed_key)
1098 }
1099
1100 fn get_sosak() -> SodiumOxideCurve25519SecretAsymmetricKey {
1101 let key_bytes: [u8; 32] = [
1102 77, 166, 178, 227, 216, 254, 219, 202, 41, 198, 74, 141, 126, 196, 68, 179, 19, 218,
1103 34, 107, 174, 121, 199, 180, 254, 254, 161, 219, 225, 158, 220, 56,
1104 ];
1105 let sosakb = SodiumOxideCurve25519SecretAsymmetricKeyBuilder {};
1106 sosakb.build(Some(&key_bytes)).unwrap()
1107 }
1108
1109 fn get_soan() -> SodiumOxideAsymmetricNonce {
1110 let nonce_bytes: [u8; 24] = [
1111 24, 101, 189, 110, 189, 19, 129, 254, 163, 80, 137, 144, 100, 21, 11, 191, 22, 47, 64,
1112 132, 80, 122, 1, 237,
1113 ];
1114 let nonce = box_::curve25519xsalsa20poly1305::Nonce::from_slice(&nonce_bytes).unwrap();
1115 SodiumOxideAsymmetricNonce { nonce }
1116 }
1117
1118 fn get_sosk_ciphertext(plaintext: &[u8]) -> Vec<u8> {
1166 let key = get_sosk();
1167 let nonce = get_sosn();
1168 secretbox::seal(plaintext, &nonce.nonce, &key.key)
1169 }
1170
1171 fn get_sosk() -> SodiumOxideSymmetricKey {
1173 let key_bytes: [u8; 32] = [
1174 188, 223, 72, 202, 66, 168, 65, 178, 120, 109, 80, 156, 14, 16, 212, 28, 77, 40, 207,
1175 216, 211, 141, 66, 62, 17, 156, 76, 160, 132, 29, 145, 18,
1176 ];
1177 let soskb = SodiumOxideSymmetricKeyBuilder {};
1178 soskb.build(Some(&key_bytes)).unwrap()
1179 }
1180
1181 fn get_sosn() -> SodiumOxideSymmetricNonce {
1183 let nonce_bytes: [u8; 24] = [
1184 13, 7, 8, 143, 25, 5, 250, 134, 70, 171, 199, 182, 68, 69, 45, 89, 178, 90, 14, 31,
1185 220, 196, 79, 116,
1186 ];
1187 SodiumOxideSymmetricNonce {
1188 nonce: ExternalSodiumOxideSymmetricNonce::from_slice(&nonce_bytes).unwrap(),
1189 }
1190 }
1191
1192 #[tokio::test]
1241 async fn test_seal_symmetricbytealgorithm_with_unsealed_key() {
1242 let data = Data::String("hello, world!".to_owned());
1243 let key = get_sosk();
1244 let algorithm = key
1245 .to_byte_algorithm(Some(get_sosn()), |key| async move {
1246 key.to_unsealed_entry(".encryptionkey.".to_owned())
1247 })
1248 .await
1249 .unwrap();
1250 let ciphertext = algorithm.seal(&data.byte_source()).await.unwrap();
1251 assert_eq!(
1252 ciphertext.get().unwrap(),
1253 get_sosk_ciphertext(b"hello, world!")
1254 );
1255 }
1256
1257 #[tokio::test]
1258 async fn test_seal_symmetricbytealgorithm_with_referenced_key() {
1259 let data = Data::String("hello, world!".to_owned());
1260 let unsealed_key = get_sosk()
1261 .to_unsealed_entry(".encryptionkey.".to_owned())
1262 .unwrap();
1263 let mut storer = MockStorer::new();
1264 storer
1265 .expect_private_get::<SodiumOxideSymmetricKey>()
1266 .withf(|path| path == ".encryptionkey.")
1267 .return_once(move |_| Ok(unsealed_key));
1268 let ref_key = get_sosk()
1269 .to_ref_entry(".encryptionkey.".to_owned(), storer)
1270 .unwrap();
1271 let algorithm = ref_key
1272 .to_symmetric_byte_algorithm(Some(get_sosn()))
1273 .await
1274 .unwrap();
1275 let ciphertext = algorithm.seal(&data.byte_source()).await.unwrap();
1276 assert_eq!(
1277 ciphertext.get().unwrap(),
1278 get_sosk_ciphertext(b"hello, world!")
1279 );
1280 }
1281
1282 #[tokio::test]
1283 async fn test_seal_symmetricbytealgorithm_with_sealed_key_with_unsealed_decryption_key() {
1284 let data = Data::String("hello, world!".to_owned());
1285 let key = get_sosk();
1286 let key_encryption_key = get_sosk();
1287 let key_encryption_algorithm = key_encryption_key
1288 .to_byte_algorithm(Some(get_sosn()), |key| async move {
1289 key.to_unsealed_entry(".keyencryptionkey.".to_owned())
1290 })
1291 .await
1292 .unwrap();
1293 let algorithm = key
1294 .to_byte_algorithm(Some(get_sosn()), |key| async move {
1295 key.to_sealed_entry(".encryptionkey.".to_owned(), key_encryption_algorithm)
1296 .await
1297 })
1298 .await
1299 .unwrap();
1300 let ciphertext = algorithm.seal(&data.byte_source()).await.unwrap();
1301 assert_eq!(
1302 ciphertext.get().unwrap(),
1303 get_sosk_ciphertext(b"hello, world!")
1304 );
1305 }
1306
1307 #[tokio::test]
1308 async fn test_seal_symmetricbytealgorithm_with_sealed_key_with_referenced_decryption_key() {
1309 let unsealed_key_encryption_key = get_sosk()
1310 .to_unsealed_entry(".keyencryptionkey.".to_owned())
1311 .unwrap();
1312 let mut storer = MockStorer::new();
1313 storer
1314 .expect_private_get::<SodiumOxideSymmetricKey>()
1315 .withf(|path| path == ".keyencryptionkey.")
1316 .return_once(move |_| Ok(unsealed_key_encryption_key));
1317 let data = Data::String("hello, world!".to_owned());
1318 let key = get_sosk();
1319 let referenced_key_encryption_key = get_sosk()
1320 .to_ref_entry(".keyencryptionkey.".to_owned(), storer)
1321 .unwrap();
1322 let key_encryption_algorithm = referenced_key_encryption_key
1323 .to_symmetric_byte_algorithm(Some(get_sosn()))
1324 .await
1325 .unwrap();
1326 let algorithm = key
1327 .to_byte_algorithm(Some(get_sosn()), |key| async move {
1328 key.to_sealed_entry(".encryptionkey.".to_owned(), key_encryption_algorithm)
1329 .await
1330 })
1331 .await
1332 .unwrap();
1333 let ciphertext = algorithm.seal(&data.byte_source()).await.unwrap();
1334 assert_eq!(
1335 ciphertext.get().unwrap(),
1336 get_sosk_ciphertext(b"hello, world!")
1337 );
1338 }
1339
1340 #[tokio::test]
1342 async fn test_unseal_symmetricbytealgorithm_with_unsealed_key() {
1343 let data = Data::String("hello, world!".to_owned());
1344 let key = get_sosk();
1345 let algorithm = key
1346 .to_byte_algorithm(Some(get_sosn()), |key| async move {
1347 key.to_unsealed_entry(".encryptionkey.".to_owned())
1348 })
1349 .await
1350 .unwrap();
1351 let ciphertext = get_sosk_ciphertext(data.byte_source().get().unwrap());
1352 let plaintext = algorithm
1353 .unseal(&ByteSource::Vector(
1354 AsRef::<[u8]>::as_ref(&ciphertext).into(),
1355 ))
1356 .await
1357 .unwrap();
1358 assert_eq!(data.byte_source().get().unwrap(), plaintext.get().unwrap());
1359 }
1360
1361 #[tokio::test]
1362 async fn test_unseal_symmetricbytealgorithm_with_referenced_key() {
1363 let data = Data::String("hello, world!".to_owned());
1364 let unsealed_key = get_sosk()
1365 .to_unsealed_entry(".encryptionkey.".to_owned())
1366 .unwrap();
1367 let mut storer = MockStorer::new();
1368 storer
1369 .expect_private_get::<SodiumOxideSymmetricKey>()
1370 .withf(|path| path == ".encryptionkey.")
1371 .return_once(move |_| Ok(unsealed_key));
1372 let ref_key = get_sosk()
1373 .to_ref_entry(".encryptionkey.".to_owned(), storer)
1374 .unwrap();
1375 let algorithm = ref_key
1376 .to_symmetric_byte_algorithm(Some(get_sosn()))
1377 .await
1378 .unwrap();
1379 let ciphertext = get_sosk_ciphertext(data.byte_source().get().unwrap());
1380 let plaintext = algorithm
1381 .unseal(&ByteSource::Vector(
1382 AsRef::<[u8]>::as_ref(&ciphertext).into(),
1383 ))
1384 .await
1385 .unwrap();
1386 assert_eq!(data.byte_source().get().unwrap(), plaintext.get().unwrap());
1387 }
1388
1389 #[tokio::test]
1390 async fn test_unseal_symmetricbytealgorithm_with_sealed_key_with_unsealed_decryption_key() {
1391 let data = Data::String("hello, world!".to_owned());
1392 let key = get_sosk();
1393 let key_encryption_key = get_sosk();
1394 let key_encryption_algorithm = key_encryption_key
1395 .to_byte_algorithm(Some(get_sosn()), |key| async move {
1396 key.to_unsealed_entry(".keyencryptionkey.".to_owned())
1397 })
1398 .await
1399 .unwrap();
1400 let algorithm = key
1401 .to_byte_algorithm(Some(get_sosn()), |key| async move {
1402 key.to_sealed_entry(".encryptionkey.".to_owned(), key_encryption_algorithm)
1403 .await
1404 })
1405 .await
1406 .unwrap();
1407 let ciphertext = get_sosk_ciphertext(data.byte_source().get().unwrap());
1408 let plaintext = algorithm
1409 .unseal(&ByteSource::Vector(
1410 AsRef::<[u8]>::as_ref(&ciphertext).into(),
1411 ))
1412 .await
1413 .unwrap();
1414 assert_eq!(data.byte_source().get().unwrap(), plaintext.get().unwrap());
1415 }
1416
1417 #[tokio::test]
1418 async fn test_unseal_symmetricbytealgorithm_with_sealed_key_with_referenced_decryption_key() {
1419 let unsealed_key_encryption_key = get_sosk()
1420 .to_unsealed_entry(".keyencryptionkey.".to_owned())
1421 .unwrap();
1422 let mut storer = MockStorer::new();
1423 storer
1424 .expect_private_get::<SodiumOxideSymmetricKey>()
1425 .withf(|path| path == ".keyencryptionkey.")
1426 .return_once(move |_| Ok(unsealed_key_encryption_key));
1427 let data = Data::String("hello, world!".to_owned());
1428 let key = get_sosk();
1429 let referenced_key_encryption_key = get_sosk()
1430 .to_ref_entry(".keyencryptionkey.".to_owned(), storer)
1431 .unwrap();
1432 let key_encryption_algorithm = referenced_key_encryption_key
1433 .to_symmetric_byte_algorithm(Some(get_sosn()))
1434 .await
1435 .unwrap();
1436 let algorithm = key
1437 .to_byte_algorithm(Some(get_sosn()), |key| async move {
1438 key.to_sealed_entry(".encryptionkey.".to_owned(), key_encryption_algorithm)
1439 .await
1440 })
1441 .await
1442 .unwrap();
1443 let ciphertext = get_sosk_ciphertext(data.byte_source().get().unwrap());
1444 let plaintext = algorithm
1445 .unseal(&ByteSource::Vector(
1446 AsRef::<[u8]>::as_ref(&ciphertext).into(),
1447 ))
1448 .await
1449 .unwrap();
1450 assert_eq!(data.byte_source().get().unwrap(), plaintext.get().unwrap());
1451 }
1452
1453 #[test]
1455 fn test_sodiumoxidesymmetrickeybuilder_build_valid() {
1456 let soskb = SodiumOxideSymmetricKeyBuilder {};
1457 let external_key = secretbox::gen_key();
1458 let key = soskb.build(Some(external_key.as_ref())).unwrap();
1459 assert_eq!(key.key.as_ref(), external_key.as_ref());
1460 }
1461
1462 #[test]
1463 #[should_panic]
1464 fn test_sodiumoxidesymmetrickeybuilder_build_invalid() {
1465 let soskb = SodiumOxideSymmetricKeyBuilder {};
1466 let _ = soskb.build(Some(b"bla")).unwrap();
1467 }
1468
1469 #[test]
1470 fn test_sodiumoxidesymmetrickeybuilder_from_typebuildercontainer_valid() {
1471 let tbc = TypeBuilderContainer(TypeBuilder::Key(KeyBuilder::Symmetric(
1472 SymmetricKeyBuilder::SodiumOxide(SodiumOxideSymmetricKeyBuilder {}),
1473 )));
1474 let soskb: SodiumOxideSymmetricKeyBuilder = tbc.try_into().unwrap();
1475 let key = SodiumOxideSymmetricKey::new();
1476 soskb.build(Some(key.key.as_ref())).unwrap();
1477 }
1478
1479 #[test]
1480 #[should_panic]
1481 fn test_sodiumoxidesymmetrickeybuilder_from_typebuildercontainer_invalid() {
1482 let tbc = TypeBuilderContainer(TypeBuilder::Data(DataBuilder::Bool(BoolDataBuilder {})));
1483 let _: SodiumOxideSymmetricKeyBuilder = tbc.try_into().unwrap();
1484 }
1485
1486 #[test]
1488 fn test_seal_symmetrickey() {
1489 let plaintext = "hello, world!".into();
1490 let sosk = get_sosk();
1491 let (cipher_source, _) = sosk.seal(&plaintext, Some(&get_sosn())).unwrap();
1492 assert_eq!(
1493 get_sosk_ciphertext(b"hello, world!"),
1494 cipher_source.get().unwrap().to_vec(),
1495 );
1496 }
1497
1498 #[test]
1499 #[should_panic(expected = "CiphertextFailedVerification")]
1500 fn test_symmetrickey_unseal_with_invalid_bytes() {
1501 let sosk = get_sosk();
1502 let ciphertext = "bla".into();
1503 let _ = sosk.unseal(&ciphertext, &get_sosn()).unwrap();
1504 }
1505
1506 #[test]
1507 #[should_panic(expected = "CiphertextFailedVerification")]
1508 fn test_symmetrickey_unseal_with_invalid_nonce() {
1509 let sosk = get_sosk();
1510 let ciphertext = get_sosk_ciphertext(b"hello, world!");
1511 let _ = sosk
1512 .unseal(
1513 &ciphertext.as_slice().into(),
1514 &SodiumOxideSymmetricNonce {
1515 nonce: secretbox::gen_nonce(),
1516 },
1517 )
1518 .unwrap();
1519 }
1520
1521 #[test]
1522 fn test_symmetrickey_to_index() {
1523 let index = SodiumOxideSymmetricKey::get_index();
1524 assert_eq!(
1525 index,
1526 Some(bson::doc! {
1527 "c": {
1528 "builder": {
1529 "t": "Key",
1530 "c": {
1531 "t": "Symmetric",
1532 "c": {
1533 "t": "SodiumOxide"
1534 }
1535 }
1536 }
1537 }
1538 })
1539 )
1540 }
1541
1542 #[test]
1543 fn test_symmetrickey_to_builder() {
1544 let sosk = SodiumOxideSymmetricKey::new();
1545 let builder = sosk.builder();
1546 let key_bytes = sosk.key.as_ref();
1547 let built_key = builder.build(Some(key_bytes)).unwrap();
1548 assert_eq!(built_key.key.as_ref(), sosk.key.as_ref());
1549 }
1550
1551 #[test]
1552 fn test_symmetrickey_new() {
1553 let sosk = SodiumOxideSymmetricKey::new();
1554 assert!(!sosk.key.as_ref().is_empty());
1555 }
1556
1557 #[tokio::test]
1563 async fn test_seal_secretasymmetricbytealgorithm_with_unsealed_key() {
1564 let data = Data::String("hello, world!".to_owned());
1565 let alice_key = get_sosak()
1566 .to_unsealed_entry(".alicesecretkey.".to_owned())
1567 .unwrap();
1568 let bob_key = SodiumOxideCurve25519SecretAsymmetricKey::new()
1569 .public_key()
1570 .unwrap()
1571 .to_unsealed_entry(".bobpublickey.".to_owned())
1572 .unwrap();
1573 let bob_key_bytes = bob_key.resolve().await.unwrap().byte_source();
1574 let algorithm = alice_key
1575 .to_secret_asymmetric_byte_algorithm(Some(bob_key), Some(get_soan()))
1576 .await
1577 .unwrap();
1578 let ciphertext = algorithm.seal(&data.byte_source()).await.unwrap();
1579 let bob_key_copy = SodiumOxideCurve25519PublicAsymmetricKeyBuilder {}
1580 .build(Some(bob_key_bytes.get().unwrap()))
1581 .unwrap();
1582 assert_eq!(
1583 ciphertext.get().unwrap(),
1584 get_sosak_ciphertext(b"hello, world!", &Some(bob_key_copy))
1585 );
1586 }
1587
1588 #[tokio::test]
1589 async fn test_seal_secretasymmetricbytealgorithm_with_referenced_key() {
1590 let data = Data::String("hello, world!".to_owned());
1591 let unsealed_alice_key = get_sosak()
1592 .to_unsealed_entry(".alicesecretkey.".to_owned())
1593 .unwrap();
1594 let unsealed_bob_key = SodiumOxideCurve25519SecretAsymmetricKey::new()
1595 .public_key()
1596 .unwrap()
1597 .to_unsealed_entry(".bobpublickey.".to_owned())
1598 .unwrap();
1599 let bob_key_bytes = unsealed_bob_key.resolve().await.unwrap().byte_source();
1600 let mut storer = MockIndexedStorer::new();
1601 storer
1602 .expect_private_get::<SodiumOxideCurve25519SecretAsymmetricKey>()
1603 .withf(|path| path == ".alicesecretkey.")
1604 .return_once(move |_| Ok(unsealed_alice_key));
1605 let ref_alice_key = get_sosak()
1606 .to_ref_entry(".alicesecretkey.".to_owned(), storer)
1607 .unwrap();
1608 let algorithm = ref_alice_key
1609 .to_secret_asymmetric_byte_algorithm(Some(unsealed_bob_key), Some(get_soan()))
1610 .await
1611 .unwrap();
1612 let ciphertext = algorithm.seal(&data.byte_source()).await.unwrap();
1613 let bob_key_copy = SodiumOxideCurve25519PublicAsymmetricKeyBuilder {}
1614 .build(Some(bob_key_bytes.get().unwrap()))
1615 .unwrap();
1616 assert_eq!(
1617 ciphertext.get().unwrap(),
1618 get_sosak_ciphertext(b"hello, world!", &Some(bob_key_copy))
1619 );
1620 }
1621
1622 #[tokio::test]
1623 async fn test_seal_secretasymmetricbytealgorithm_with_sealed_key_with_unsealed_decryption_key()
1624 {
1625 let data = Data::String("hello, world!".to_owned());
1626 let alice_decryption_key = get_sosk()
1627 .to_unsealed_entry(".alicedecryptionkey.".to_owned())
1628 .unwrap();
1629 let alice_decryption_algorithm = alice_decryption_key
1630 .to_symmetric_byte_algorithm(Some(get_sosn()))
1631 .await
1632 .unwrap();
1633 let alice_key = get_sosak()
1634 .to_sealed_entry(".alicesecretkey.".to_owned(), alice_decryption_algorithm)
1635 .await
1636 .unwrap();
1637 let bob_key = SodiumOxideCurve25519SecretAsymmetricKey::new()
1638 .public_key()
1639 .unwrap()
1640 .to_unsealed_entry(".bobpublickey.".to_owned())
1641 .unwrap();
1642 let bob_key_bytes = bob_key.resolve().await.unwrap().byte_source();
1643 let algorithm = alice_key
1644 .to_secret_asymmetric_byte_algorithm(Some(bob_key), Some(get_soan()))
1645 .await
1646 .unwrap();
1647 let ciphertext = algorithm.seal(&data.byte_source()).await.unwrap();
1648 let bob_key_copy = SodiumOxideCurve25519PublicAsymmetricKeyBuilder {}
1649 .build(Some(bob_key_bytes.get().unwrap()))
1650 .unwrap();
1651 assert_eq!(
1652 ciphertext.get().unwrap(),
1653 get_sosak_ciphertext(b"hello, world!", &Some(bob_key_copy))
1654 );
1655 }
1656
1657 #[tokio::test]
1658 async fn test_seal_secretasymmetricbytealgorithm_with_sealed_key_with_referenced_decryption_key(
1659 ) {
1660 let data = Data::String("hello, world!".to_owned());
1661 let unsealed_alice_decryption_key = get_sosk()
1662 .to_unsealed_entry(".alicedecryptionkey.".to_owned())
1663 .unwrap();
1664 let mut storer = MockStorer::new();
1665 storer
1666 .expect_private_get::<SodiumOxideSymmetricKey>()
1667 .withf(|path| path == ".alicedecryptionkey.")
1668 .return_once(move |_| Ok(unsealed_alice_decryption_key));
1669 let ref_alice_decryption_key = get_sosk()
1670 .to_ref_entry(".alicedecryptionkey.".to_owned(), storer)
1671 .unwrap();
1672 let alice_decryption_algorithm = ref_alice_decryption_key
1673 .to_symmetric_byte_algorithm(Some(get_sosn()))
1674 .await
1675 .unwrap();
1676 let sealed_alice_key = get_sosak()
1677 .to_sealed_entry(".alicesecretkey.".to_owned(), alice_decryption_algorithm)
1678 .await
1679 .unwrap();
1680 let unsealed_bob_key = SodiumOxideCurve25519SecretAsymmetricKey::new()
1681 .public_key()
1682 .unwrap()
1683 .to_unsealed_entry(".bobpublickey.".to_owned())
1684 .unwrap();
1685 let bob_key_bytes = unsealed_bob_key.resolve().await.unwrap().byte_source();
1686 let algorithm = sealed_alice_key
1687 .to_secret_asymmetric_byte_algorithm(Some(unsealed_bob_key), Some(get_soan()))
1688 .await
1689 .unwrap();
1690 let ciphertext = algorithm.seal(&data.byte_source()).await.unwrap();
1691 let bob_key_copy = SodiumOxideCurve25519PublicAsymmetricKeyBuilder {}
1692 .build(Some(bob_key_bytes.get().unwrap()))
1693 .unwrap();
1694 assert_eq!(
1695 ciphertext.get().unwrap(),
1696 get_sosak_ciphertext(b"hello, world!", &Some(bob_key_copy))
1697 );
1698 }
1699
1700 #[tokio::test]
1702 async fn test_unseal_secretasymmetricbytealgorithm_with_unsealed_key() {
1703 let data = Data::String("hello, world!".to_owned());
1704 let alice_key = get_sosak()
1705 .to_unsealed_entry(".alicesecretkey.".to_owned())
1706 .unwrap();
1707 let bob_key = SodiumOxideCurve25519SecretAsymmetricKey::new()
1708 .public_key()
1709 .unwrap()
1710 .to_unsealed_entry(".bobpublickey.".to_owned())
1711 .unwrap();
1712 let bob_key_bytes = bob_key.resolve().await.unwrap().byte_source();
1713 let bob_key_copy = SodiumOxideCurve25519PublicAsymmetricKeyBuilder {}
1714 .build(Some(bob_key_bytes.get().unwrap()))
1715 .unwrap();
1716 let ciphertext = get_sosak_ciphertext(b"hello, world!", &Some(bob_key_copy));
1717 let algorithm = alice_key
1718 .to_secret_asymmetric_byte_algorithm(Some(bob_key), Some(get_soan()))
1719 .await
1720 .unwrap();
1721 let plaintext = algorithm
1722 .unseal(&ByteSource::Vector(
1723 AsRef::<[u8]>::as_ref(&ciphertext).into(),
1724 ))
1725 .await
1726 .unwrap();
1727 assert_eq!(data.byte_source().get().unwrap(), plaintext.get().unwrap());
1728 }
1729
1730 #[tokio::test]
1731 async fn test_unseal_secretasymmetricbytealgorithm_with_referenced_key() {
1732 let data = Data::String("hello, world!".to_owned());
1733 let unsealed_alice_key = get_sosak()
1734 .to_unsealed_entry(".alicesecretkey.".to_owned())
1735 .unwrap();
1736 let unsealed_bob_key = SodiumOxideCurve25519SecretAsymmetricKey::new()
1737 .public_key()
1738 .unwrap()
1739 .to_unsealed_entry(".bobpublickey.".to_owned())
1740 .unwrap();
1741 let bob_key_bytes = unsealed_bob_key.resolve().await.unwrap().byte_source();
1742 let bob_key_copy = SodiumOxideCurve25519PublicAsymmetricKeyBuilder {}
1743 .build(Some(bob_key_bytes.get().unwrap()))
1744 .unwrap();
1745 let mut storer = MockStorer::new();
1746 storer
1747 .expect_private_get::<SodiumOxideCurve25519SecretAsymmetricKey>()
1748 .withf(|path| path == ".alicesecretkey.")
1749 .return_once(move |_| Ok(unsealed_alice_key));
1750 let ref_alice_key = get_sosak()
1751 .to_ref_entry(".alicesecretkey.".to_owned(), storer)
1752 .unwrap();
1753 let ciphertext = get_sosak_ciphertext(b"hello, world!", &Some(bob_key_copy));
1754 let algorithm = ref_alice_key
1755 .to_secret_asymmetric_byte_algorithm(Some(unsealed_bob_key), Some(get_soan()))
1756 .await
1757 .unwrap();
1758 let plaintext = algorithm
1759 .unseal(&ByteSource::Vector(
1760 AsRef::<[u8]>::as_ref(&ciphertext).into(),
1761 ))
1762 .await
1763 .unwrap();
1764 assert_eq!(data.byte_source().get().unwrap(), plaintext.get().unwrap());
1765 }
1766
1767 #[tokio::test]
1768 async fn test_unseal_secretasymmetricbytealgorithm_with_sealed_key_with_unsealed_decryption_key(
1769 ) {
1770 let data = Data::String("hello, world!".to_owned());
1771 let alice_decryption_key = get_sosk()
1772 .to_unsealed_entry(".alicedecryptionkey.".to_owned())
1773 .unwrap();
1774 let alice_decryption_algorithm = alice_decryption_key
1775 .to_symmetric_byte_algorithm(Some(get_sosn()))
1776 .await
1777 .unwrap();
1778 let alice_key = get_sosak()
1779 .to_sealed_entry(".alicesecretkey.".to_owned(), alice_decryption_algorithm)
1780 .await
1781 .unwrap();
1782 let bob_key = SodiumOxideCurve25519SecretAsymmetricKey::new()
1783 .public_key()
1784 .unwrap()
1785 .to_unsealed_entry(".bobpublickey.".to_owned())
1786 .unwrap();
1787 let bob_key_bytes = bob_key.resolve().await.unwrap().byte_source();
1788 let bob_key_copy = SodiumOxideCurve25519PublicAsymmetricKeyBuilder {}
1789 .build(Some(bob_key_bytes.get().unwrap()))
1790 .unwrap();
1791 let ciphertext = get_sosak_ciphertext(b"hello, world!", &Some(bob_key_copy));
1792 let algorithm = alice_key
1793 .to_secret_asymmetric_byte_algorithm(Some(bob_key), Some(get_soan()))
1794 .await
1795 .unwrap();
1796 let plaintext = algorithm
1797 .unseal(&ByteSource::Vector(
1798 AsRef::<[u8]>::as_ref(&ciphertext).into(),
1799 ))
1800 .await
1801 .unwrap();
1802 assert_eq!(data.byte_source().get().unwrap(), plaintext.get().unwrap());
1803 }
1804
1805 #[tokio::test]
1806 async fn test_unseal_secretasymmetricbytealgorithm_with_sealed_key_with_referenced_decryption_key(
1807 ) {
1808 let data = Data::String("hello, world!".to_owned());
1809 let unsealed_alice_decryption_key = get_sosk()
1810 .to_unsealed_entry(".alicedecryptionkey.".to_owned())
1811 .unwrap();
1812 let mut storer = MockStorer::new();
1813 storer
1814 .expect_private_get::<SodiumOxideSymmetricKey>()
1815 .withf(|path| path == ".alicedecryptionkey.")
1816 .return_once(move |_| Ok(unsealed_alice_decryption_key));
1817 let ref_alice_decryption_key = get_sosk()
1818 .to_ref_entry(".alicedecryptionkey.".to_owned(), storer)
1819 .unwrap();
1820 let alice_decryption_algorithm = ref_alice_decryption_key
1821 .to_symmetric_byte_algorithm(Some(get_sosn()))
1822 .await
1823 .unwrap();
1824 let sealed_alice_key = get_sosak()
1825 .to_sealed_entry(".alicesecretkey.".to_owned(), alice_decryption_algorithm)
1826 .await
1827 .unwrap();
1828 let unsealed_bob_key = SodiumOxideCurve25519SecretAsymmetricKey::new()
1829 .public_key()
1830 .unwrap()
1831 .to_unsealed_entry(".bobpublickey.".to_owned())
1832 .unwrap();
1833 let bob_key_bytes = unsealed_bob_key.resolve().await.unwrap().byte_source();
1834 let bob_key_copy = SodiumOxideCurve25519PublicAsymmetricKeyBuilder {}
1835 .build(Some(bob_key_bytes.get().unwrap()))
1836 .unwrap();
1837 let ciphertext = get_sosak_ciphertext(b"hello, world!", &Some(bob_key_copy));
1838 let algorithm = sealed_alice_key
1839 .to_secret_asymmetric_byte_algorithm(Some(unsealed_bob_key), Some(get_soan()))
1840 .await
1841 .unwrap();
1842 let plaintext = algorithm
1843 .unseal(&ByteSource::Vector(
1844 AsRef::<[u8]>::as_ref(&ciphertext).into(),
1845 ))
1846 .await
1847 .unwrap();
1848 assert_eq!(data.byte_source().get().unwrap(), plaintext.get().unwrap(),);
1849 }
1850
1851 #[test]
1853 fn test_sodiumoxidesecretasymmetrickeybuilder_build_valid() {
1854 let sosakb = SodiumOxideCurve25519SecretAsymmetricKeyBuilder {};
1855 let (_, sk) = box_::gen_keypair();
1856 let key = sosakb.build(Some(sk.as_ref())).unwrap();
1857 assert_eq!(key.secret_key.as_ref(), sk.as_ref());
1858 }
1859
1860 #[test]
1861 #[should_panic]
1862 fn test_sodiumoxidesecretasymmetrickeybuilder_build_invalid() {
1863 let sosakb = SodiumOxideCurve25519SecretAsymmetricKeyBuilder {};
1864 let _ = sosakb.build(Some(b"bla")).unwrap();
1865 }
1866
1867 #[test]
1868 fn test_sodiumoxidesecretasymmetrickeybuilder_from_typebuildercontainer_valid() {
1869 let tbc = TypeBuilderContainer(TypeBuilder::Key(KeyBuilder::Asymmetric(
1870 AsymmetricKeyBuilder::Secret(SecretAsymmetricKeyBuilder::SodiumOxideCurve25519(
1871 SodiumOxideCurve25519SecretAsymmetricKeyBuilder {},
1872 )),
1873 )));
1874 let sosakb: SodiumOxideCurve25519SecretAsymmetricKeyBuilder = tbc.try_into().unwrap();
1875 let key = SodiumOxideCurve25519SecretAsymmetricKey::new();
1876 sosakb.build(Some(key.secret_key.as_ref())).unwrap();
1877 }
1878
1879 #[test]
1880 #[should_panic]
1881 fn test_sodiumoxidesecretasymmetrickeybuilder_from_typebuildercontainer_invalid() {
1882 let tbc = TypeBuilderContainer(TypeBuilder::Data(DataBuilder::Bool(BoolDataBuilder {})));
1883 let _: SodiumOxideCurve25519SecretAsymmetricKeyBuilder = tbc.try_into().unwrap();
1884 }
1885
1886 #[test]
1888 fn test_seal_secretasymmetrickey_with_non_referenced_key() {
1889 let plaintext = "hello, world!".into();
1890 let sosak = get_sosak();
1891 let (cipher_source, _) = sosak.seal(&plaintext, None, Some(&get_soan())).unwrap();
1892 assert_eq!(
1893 get_sosak_ciphertext(b"hello, world!", &None),
1894 cipher_source.get().unwrap().to_vec(),
1895 );
1896 }
1897
1898 #[test]
1899 #[should_panic(expected = "CiphertextFailedVerification")]
1900 fn test_secretasymmetrickey_unseal_with_invalid_bytes() {
1901 let sosak = get_sosak();
1902 let ciphertext = "bla".into();
1903 let _ = sosak.unseal(&ciphertext, None, &get_soan()).unwrap();
1904 }
1905
1906 #[test]
1907 #[should_panic(expected = "CiphertextFailedVerification")]
1908 fn test_secretasymmetrickey_unseal_with_invalid_nonce() {
1909 let sosak = get_sosak();
1910 let ciphertext = get_sosak_ciphertext(b"hello, world!", &None);
1911 let _ = sosak
1912 .unseal(
1913 &ciphertext.as_slice().into(),
1914 None,
1915 &SodiumOxideAsymmetricNonce {
1916 nonce: box_::gen_nonce(),
1917 },
1918 )
1919 .unwrap();
1920 }
1921
1922 #[test]
1923 fn test_secretasymmetrickey_to_index() {
1924 let index = SodiumOxideCurve25519SecretAsymmetricKey::get_index();
1925 assert_eq!(
1926 index,
1927 Some(bson::doc! {
1928 "c": {
1929 "builder": {
1930 "t": "Key",
1931 "c": {
1932 "t": "Asymmetric",
1933 "c": {
1934 "t": "Secret",
1935 "c": {
1936 "t": "SodiumOxideCurve25519"
1937 }
1938 }
1939 }
1940 }
1941 }
1942 })
1943 )
1944 }
1945
1946 #[test]
1947 fn test_secretasymmetrickey_to_builder() {
1948 let sosak = SodiumOxideCurve25519SecretAsymmetricKey::new();
1949 let builder = sosak.builder();
1950 let key_bytes = sosak.secret_key.as_ref();
1951 let built_key = builder.build(Some(key_bytes)).unwrap();
1952 assert_eq!(built_key.secret_key.as_ref(), sosak.secret_key.as_ref());
1953 }
1954
1955 #[test]
1956 fn test_secretasymmetrickey_new() {
1957 let sosak = SodiumOxideCurve25519SecretAsymmetricKey::new();
1958 assert!(!sosak.secret_key.as_ref().is_empty());
1959 }
1960
1961 #[tokio::test]
1967 async fn test_seal_publicasymmetricbytealgorithm_with_unsealed_key() {
1968 let data = Data::String("hello, world!".to_owned());
1969 let (alice_public_key, _) = get_sopak();
1970 let unsealed_alice_public_key = alice_public_key
1971 .to_unsealed_entry(".alicepublickey.".to_owned())
1972 .unwrap();
1973 let bob_key = SodiumOxideCurve25519SecretAsymmetricKey::new()
1974 .to_unsealed_entry(".bobsecretkey.".to_owned())
1975 .unwrap();
1976 let bob_key_bytes = bob_key.resolve().await.unwrap().byte_source();
1977 let algorithm = unsealed_alice_public_key
1978 .to_public_asymmetric_byte_algorithm(bob_key, Some(get_soan()))
1979 .await
1980 .unwrap();
1981 let ciphertext = algorithm.seal(&data.byte_source()).await.unwrap();
1982 let bob_key_copy = SodiumOxideCurve25519SecretAsymmetricKeyBuilder {}
1983 .build(Some(bob_key_bytes.get().unwrap()))
1984 .unwrap();
1985 assert_eq!(
1986 ciphertext.get().unwrap(),
1987 get_sopak_ciphertext(b"hello, world!", Some(&bob_key_copy))
1988 );
1989 }
1990
1991 #[tokio::test]
1992 async fn test_seal_publicasymmetricbytealgorithm_with_referenced_key() {
1993 let data = Data::String("hello, world!".to_owned());
1994 let (alice_public_key, _) = get_sopak();
1995 let unsealed_alice_public_key = alice_public_key
1996 .to_unsealed_entry(".alicepublickey.".to_owned())
1997 .unwrap();
1998 let unsealed_bob_key = SodiumOxideCurve25519SecretAsymmetricKey::new()
1999 .to_unsealed_entry(".bobsecretkey.".to_owned())
2000 .unwrap();
2001 let bob_key_bytes = unsealed_bob_key.resolve().await.unwrap().byte_source();
2002 let mut storer = MockStorer::new();
2003 storer
2004 .expect_private_get::<SodiumOxideCurve25519PublicAsymmetricKey>()
2005 .withf(|path| path == ".alicepublickey.")
2006 .return_once(move |_| Ok(unsealed_alice_public_key));
2007 let (alice_public_key, _) = get_sopak();
2008 let ref_alice_public_key = alice_public_key
2009 .to_ref_entry(".alicepublickey.".to_owned(), storer)
2010 .unwrap();
2011 let algorithm = ref_alice_public_key
2012 .to_public_asymmetric_byte_algorithm(unsealed_bob_key, Some(get_soan()))
2013 .await
2014 .unwrap();
2015 let ciphertext = algorithm.seal(&data.byte_source()).await.unwrap();
2016 let bob_key_copy = SodiumOxideCurve25519SecretAsymmetricKeyBuilder {}
2017 .build(Some(bob_key_bytes.get().unwrap()))
2018 .unwrap();
2019 assert_eq!(
2020 ciphertext.get().unwrap(),
2021 get_sopak_ciphertext(b"hello, world!", Some(&bob_key_copy))
2022 );
2023 }
2024
2025 #[tokio::test]
2026 async fn test_seal_publicasymmetricbytealgorithm_with_sealed_key_with_unsealed_decryption_key()
2027 {
2028 let data = Data::String("hello, world!".to_owned());
2029 let alice_decryption_key = get_sosk()
2030 .to_unsealed_entry(".alicedecryptionkey.".to_owned())
2031 .unwrap();
2032 let alice_decryption_algorithm = alice_decryption_key
2033 .to_symmetric_byte_algorithm(Some(get_sosn()))
2034 .await
2035 .unwrap();
2036 let (alice_public_key, _) = get_sopak();
2037 let sealed_alice_public_key = alice_public_key
2038 .to_sealed_entry(".alicepublickey.".to_owned(), alice_decryption_algorithm)
2039 .await
2040 .unwrap();
2041 let bob_key = SodiumOxideCurve25519SecretAsymmetricKey::new()
2042 .to_unsealed_entry(".bobsecretkey.".to_owned())
2043 .unwrap();
2044 let bob_key_bytes = bob_key.resolve().await.unwrap().byte_source();
2045 let algorithm = sealed_alice_public_key
2046 .to_public_asymmetric_byte_algorithm(bob_key, Some(get_soan()))
2047 .await
2048 .unwrap();
2049 let ciphertext = algorithm.seal(&data.byte_source()).await.unwrap();
2050 let bob_key_copy = SodiumOxideCurve25519SecretAsymmetricKeyBuilder {}
2051 .build(Some(bob_key_bytes.get().unwrap()))
2052 .unwrap();
2053 assert_eq!(
2054 ciphertext.get().unwrap(),
2055 get_sopak_ciphertext(b"hello, world!", Some(&bob_key_copy))
2056 );
2057 }
2058
2059 #[tokio::test]
2060 async fn test_seal_publicasymmetricbytealgorithm_with_sealed_key_with_referenced_decryption_key(
2061 ) {
2062 let data = Data::String("hello, world!".to_owned());
2063 let unsealed_alice_decryption_key = get_sosk()
2064 .to_unsealed_entry(".alicedecryptionkey.".to_owned())
2065 .unwrap();
2066 let mut storer = MockStorer::new();
2067 storer
2068 .expect_private_get::<SodiumOxideSymmetricKey>()
2069 .withf(|path| path == ".alicedecryptionkey.")
2070 .return_once(move |_| Ok(unsealed_alice_decryption_key));
2071 let ref_alice_decryption_key = get_sosk()
2072 .to_ref_entry(".alicedecryptionkey.".to_owned(), storer)
2073 .unwrap();
2074 let alice_decryption_algorithm = ref_alice_decryption_key
2075 .to_symmetric_byte_algorithm(Some(get_sosn()))
2076 .await
2077 .unwrap();
2078 let (alice_public_key, _) = get_sopak();
2079 let sealed_alice_public_key = alice_public_key
2080 .to_sealed_entry(".alicepublickey.".to_owned(), alice_decryption_algorithm)
2081 .await
2082 .unwrap();
2083 let unsealed_bob_key = SodiumOxideCurve25519SecretAsymmetricKey::new()
2084 .to_unsealed_entry(".bobsecretkey.".to_owned())
2085 .unwrap();
2086 let bob_key_bytes = unsealed_bob_key.resolve().await.unwrap().byte_source();
2087 let algorithm = sealed_alice_public_key
2088 .to_public_asymmetric_byte_algorithm(unsealed_bob_key, Some(get_soan()))
2089 .await
2090 .unwrap();
2091 let ciphertext = algorithm.seal(&data.byte_source()).await.unwrap();
2092 let bob_key_copy = SodiumOxideCurve25519SecretAsymmetricKeyBuilder {}
2093 .build(Some(bob_key_bytes.get().unwrap()))
2094 .unwrap();
2095 assert_eq!(
2096 ciphertext.get().unwrap(),
2097 get_sopak_ciphertext(b"hello, world!", Some(&bob_key_copy))
2098 );
2099 }
2100
2101 #[tokio::test]
2103 async fn test_unseal_publicasymmetricbytealgorithm_with_unsealed_key() {
2104 let data = Data::String("hello, world!".to_owned());
2105 let (alice_public_key, _) = get_sopak();
2106 let unsealed_alice_public_key = alice_public_key
2107 .to_unsealed_entry(".alicepublickey.".to_owned())
2108 .unwrap();
2109 let bob_key = SodiumOxideCurve25519SecretAsymmetricKey::new()
2110 .to_unsealed_entry(".bobsecretkey.".to_owned())
2111 .unwrap();
2112 let bob_key_bytes = bob_key.resolve().await.unwrap().byte_source();
2113 let bob_key_copy = SodiumOxideCurve25519SecretAsymmetricKeyBuilder {}
2114 .build(Some(bob_key_bytes.get().unwrap()))
2115 .unwrap();
2116 let ciphertext = get_sopak_ciphertext(b"hello, world!", Some(&bob_key_copy));
2117 let algorithm = unsealed_alice_public_key
2118 .to_public_asymmetric_byte_algorithm(bob_key, Some(get_soan()))
2119 .await
2120 .unwrap();
2121 let plaintext = algorithm
2122 .unseal(&ByteSource::Vector(
2123 AsRef::<[u8]>::as_ref(&ciphertext).into(),
2124 ))
2125 .await
2126 .unwrap();
2127 assert_eq!(data.byte_source().get().unwrap(), plaintext.get().unwrap());
2128 }
2129
2130 #[tokio::test]
2131 async fn test_unseal_publicasymmetricbytealgorithm_with_referenced_key() {
2132 let data = Data::String("hello, world!".to_owned());
2133 let (alice_public_key, _) = get_sopak();
2134 let unsealed_alice_public_key = alice_public_key
2135 .to_unsealed_entry(".alicepublickey.".to_owned())
2136 .unwrap();
2137 let unsealed_bob_key = SodiumOxideCurve25519SecretAsymmetricKey::new()
2138 .to_unsealed_entry(".bobsecretkey.".to_owned())
2139 .unwrap();
2140 let bob_key_bytes = unsealed_bob_key.resolve().await.unwrap().byte_source();
2141 let bob_key_copy = SodiumOxideCurve25519SecretAsymmetricKeyBuilder {}
2142 .build(Some(bob_key_bytes.get().unwrap()))
2143 .unwrap();
2144 let mut storer = MockStorer::new();
2145 storer
2146 .expect_private_get::<SodiumOxideCurve25519PublicAsymmetricKey>()
2147 .withf(|path| path == ".alicepublickey.")
2148 .return_once(move |_| Ok(unsealed_alice_public_key));
2149 let (alice_public_key, _) = get_sopak();
2150 let ref_alice_public_key = alice_public_key
2151 .to_ref_entry(".alicepublickey.".to_owned(), storer)
2152 .unwrap();
2153 let ciphertext = get_sopak_ciphertext(b"hello, world!", Some(&bob_key_copy));
2154 let algorithm = ref_alice_public_key
2155 .to_public_asymmetric_byte_algorithm(unsealed_bob_key, Some(get_soan()))
2156 .await
2157 .unwrap();
2158 let plaintext = algorithm
2159 .unseal(&ByteSource::Vector(
2160 AsRef::<[u8]>::as_ref(&ciphertext).into(),
2161 ))
2162 .await
2163 .unwrap();
2164 assert_eq!(data.byte_source().get().unwrap(), plaintext.get().unwrap());
2165 }
2166
2167 #[tokio::test]
2168 async fn test_unseal_publicasymmetricbytealgorithm_with_sealed_key_with_unsealed_decryption_key(
2169 ) {
2170 let data = Data::String("hello, world!".to_owned());
2171 let alice_decryption_key = get_sosk()
2172 .to_unsealed_entry(".alicedecryptionkey.".to_owned())
2173 .unwrap();
2174 let alice_decryption_algorithm = alice_decryption_key
2175 .to_symmetric_byte_algorithm(Some(get_sosn()))
2176 .await
2177 .unwrap();
2178 let (alice_public_key, _) = get_sopak();
2179 let sealed_alice_public_key = alice_public_key
2180 .to_sealed_entry(".alicepublickey.".to_owned(), alice_decryption_algorithm)
2181 .await
2182 .unwrap();
2183 let bob_key = SodiumOxideCurve25519SecretAsymmetricKey::new()
2184 .to_unsealed_entry(".bobsecretkey.".to_owned())
2185 .unwrap();
2186 let bob_key_bytes = bob_key.resolve().await.unwrap().byte_source();
2187 let bob_key_copy = SodiumOxideCurve25519SecretAsymmetricKeyBuilder {}
2188 .build(Some(bob_key_bytes.get().unwrap()))
2189 .unwrap();
2190 let ciphertext = get_sopak_ciphertext(b"hello, world!", Some(&bob_key_copy));
2191 let algorithm = sealed_alice_public_key
2192 .to_public_asymmetric_byte_algorithm(bob_key, Some(get_soan()))
2193 .await
2194 .unwrap();
2195 let plaintext = algorithm
2196 .unseal(&ByteSource::Vector(
2197 AsRef::<[u8]>::as_ref(&ciphertext).into(),
2198 ))
2199 .await
2200 .unwrap();
2201 assert_eq!(data.byte_source().get().unwrap(), plaintext.get().unwrap());
2202 }
2203
2204 #[tokio::test]
2205 async fn test_unseal_publicasymmetricbytealgorithm_with_sealed_key_with_referenced_decryption_key(
2206 ) {
2207 let data = Data::String("hello, world!".to_owned());
2208 let unsealed_alice_decryption_key = get_sosk()
2209 .to_unsealed_entry(".alicedecryptionkey.".to_owned())
2210 .unwrap();
2211 let mut storer = MockStorer::new();
2212 storer
2213 .expect_private_get::<SodiumOxideSymmetricKey>()
2214 .withf(|path| path == ".alicedecryptionkey.")
2215 .return_once(move |_| Ok(unsealed_alice_decryption_key));
2216 let ref_alice_decryption_key = get_sosk()
2217 .to_ref_entry(".alicedecryptionkey.".to_owned(), storer)
2218 .unwrap();
2219 let alice_decryption_algorithm = ref_alice_decryption_key
2220 .to_symmetric_byte_algorithm(Some(get_sosn()))
2221 .await
2222 .unwrap();
2223 let (alice_public_key, _) = get_sopak();
2224 let sealed_alice_key = alice_public_key
2225 .to_sealed_entry(".alicepublickey.".to_owned(), alice_decryption_algorithm)
2226 .await
2227 .unwrap();
2228 let unsealed_bob_key = SodiumOxideCurve25519SecretAsymmetricKey::new()
2229 .to_unsealed_entry(".bobsecretkey.".to_owned())
2230 .unwrap();
2231 let bob_key_bytes = unsealed_bob_key.resolve().await.unwrap().byte_source();
2232 let bob_key_copy = SodiumOxideCurve25519SecretAsymmetricKeyBuilder {}
2233 .build(Some(bob_key_bytes.get().unwrap()))
2234 .unwrap();
2235 let ciphertext = get_sopak_ciphertext(b"hello, world!", Some(&bob_key_copy));
2236 let algorithm = sealed_alice_key
2237 .to_public_asymmetric_byte_algorithm(unsealed_bob_key, Some(get_soan()))
2238 .await
2239 .unwrap();
2240 let plaintext = algorithm
2241 .unseal(&ByteSource::Vector(
2242 AsRef::<[u8]>::as_ref(&ciphertext).into(),
2243 ))
2244 .await
2245 .unwrap();
2246 assert_eq!(data.byte_source().get().unwrap(), plaintext.get().unwrap(),);
2247 }
2248
2249 #[test]
2250 fn test_sodiumoxideed25519publicasymmetrickey_verify() {
2251 let sopakb = SodiumOxideEd25519PublicAsymmetricKeyBuilder {};
2252 let public_key_base64 = "ovk3UE3A2xCRUErmWiOFFBbflsAxb67gG+i3UUQpJ/w=";
2253 let public_key: SodiumOxideEd25519PublicAsymmetricKey = sopakb
2254 .build(Some(base64::decode(public_key_base64).unwrap().as_ref()))
2255 .unwrap();
2256 let message = ByteSource::Vector(VectorByteSource::new(Some("abc".as_ref())));
2257 let signature = ByteSource::Vector(
2258 VectorByteSource::new(
2259 Some(base64::decode("XZOGd+nbEkrP5cdAjed0DdjLCrhMTW3/PU2UztdTK241N2yQyG/GVPxC+jHm96+QDFMssxHU1mMm2+e4e3m7Cw==")
2260 .unwrap()
2261 .as_ref())
2262 )
2263 );
2264
2265 public_key.verify(message, signature).unwrap();
2266 }
2267
2268 #[test]
2269 fn test_sodiumoxideed25519publicasymmetrickey_verify_with_different_message() {
2270 let sopakb = SodiumOxideEd25519PublicAsymmetricKeyBuilder {};
2271 let public_key_base64 = "ovk3UE3A2xCRUErmWiOFFBbflsAxb67gG+i3UUQpJ/w=";
2272 let public_key: SodiumOxideEd25519PublicAsymmetricKey = sopakb
2273 .build(Some(base64::decode(public_key_base64).unwrap().as_ref()))
2274 .unwrap();
2275 let message = ByteSource::Vector(VectorByteSource::new(
2276 Some("abcde".as_ref()), ));
2278 let signature = ByteSource::Vector(
2279 VectorByteSource::new(
2280 Some(base64::decode("XZOGd+nbEkrP5cdAjed0DdjLCrhMTW3/PU2UztdTK241N2yQyG/GVPxC+jHm96+QDFMssxHU1mMm2+e4e3m7Cw==")
2281 .unwrap()
2282 .as_ref())
2283 )
2284 );
2285
2286 let result = public_key.verify(message, signature);
2287 assert!(matches!(result, Err(CryptoError::BadSignature)));
2288 }
2289
2290 #[test]
2291 fn test_sodiumoxideed25519publicasymmetrickey_verify_with_invalid_signature() {
2292 let sopakb = SodiumOxideEd25519PublicAsymmetricKeyBuilder {};
2293 let (pk, _) = sign::gen_keypair();
2295 let public_key: SodiumOxideEd25519PublicAsymmetricKey =
2296 sopakb.build(Some(pk.as_ref())).unwrap();
2297
2298 let message = ByteSource::Vector(VectorByteSource::new(Some("abc".as_ref())));
2299 let signature = ByteSource::Vector(
2300 VectorByteSource::new(
2301 Some(base64::decode("XZOGd+nbEkrP5cdAjed0DdjLCrhMTW3/PU2UztdTK241N2yQyG/GVPxC+jHm96+QDFMssxHU1mMm2+e4e3m7Cw==")
2302 .unwrap()
2303 .as_ref())
2304 )
2305 );
2306 assert!(matches!(
2307 public_key.verify(message, signature),
2308 Err(CryptoError::BadSignature)
2309 ));
2310 }
2311
2312 #[test]
2313 fn test_sodiumoxideed25519publicasymmetrickey_verify_with_invalid_signature_bytes() {
2314 let sopakb = SodiumOxideEd25519PublicAsymmetricKeyBuilder {};
2315 let (pk, _) = sign::gen_keypair();
2317 let public_key: SodiumOxideEd25519PublicAsymmetricKey =
2318 sopakb.build(Some(pk.as_ref())).unwrap();
2319
2320 let message = ByteSource::Vector(VectorByteSource::new(Some("abc".as_ref())));
2321 let signature = ByteSource::Vector(VectorByteSource::new(Some(
2322 base64::decode("YWFzZA==").unwrap().as_ref(),
2323 )));
2324 assert!(matches!(
2325 public_key.verify(message, signature),
2326 Err(CryptoError::BadSignature)
2327 ));
2328 }
2329
2330 #[test]
2332 fn test_sodiumoxidepublicasymmetrickeybuilder_build_valid() {
2333 let sopakb = SodiumOxideCurve25519PublicAsymmetricKeyBuilder {};
2334 let (_, sk) = box_::gen_keypair();
2335 let key = sopakb.build(Some(sk.as_ref())).unwrap();
2336 assert_eq!(key.public_key.as_ref(), sk.as_ref());
2337 }
2338
2339 #[test]
2340 #[should_panic]
2341 fn test_sodiumoxidepublicasymmetrickeybuilder_build_invalid() {
2342 let sopakb = SodiumOxideCurve25519PublicAsymmetricKeyBuilder {};
2343 let _ = sopakb.build(Some(b"bla")).unwrap();
2344 }
2345
2346 #[test]
2347 fn test_sodiumoxidepublicasymmetrickeybuilder_from_typebuildercontainer_valid() {
2348 let tbc = TypeBuilderContainer(TypeBuilder::Key(KeyBuilder::Asymmetric(
2349 AsymmetricKeyBuilder::Public(PublicAsymmetricKeyBuilder::SodiumOxideCurve25519(
2350 SodiumOxideCurve25519PublicAsymmetricKeyBuilder {},
2351 )),
2352 )));
2353 let sopakb: SodiumOxideCurve25519PublicAsymmetricKeyBuilder = tbc.try_into().unwrap();
2354 let (public_key, _) = SodiumOxideCurve25519PublicAsymmetricKey::new();
2355 sopakb.build(Some(public_key.public_key.as_ref())).unwrap();
2356 }
2357
2358 #[test]
2359 #[should_panic]
2360 fn test_sodiumoxidepublicasymmetrickeybuilder_from_typebuildercontainer_invalid() {
2361 let tbc = TypeBuilderContainer(TypeBuilder::Data(DataBuilder::Bool(BoolDataBuilder {})));
2362 let _: SodiumOxideCurve25519PublicAsymmetricKeyBuilder = tbc.try_into().unwrap();
2363 }
2364
2365 #[test]
2367 fn test_seal_publicasymmetrickey_with_non_referenced_key() {
2368 let plaintext = "hello, world!".into();
2369 let (sopak, sosak) = get_sopak();
2370 let (cipher_source, _) = sopak.seal(&plaintext, &sosak, Some(&get_soan())).unwrap();
2371 assert_eq!(
2372 get_sopak_ciphertext(b"hello, world!", None),
2373 cipher_source.get().unwrap().to_vec(),
2374 );
2375 }
2376
2377 #[test]
2378 #[should_panic(expected = "CiphertextFailedVerification")]
2379 fn test_publicasymmetrickey_unseal_with_invalid_bytes() {
2380 let (sopak, sosak) = get_sopak();
2381 let ciphertext = "bla".into();
2382 let _ = sopak.unseal(&ciphertext, &sosak, &get_soan()).unwrap();
2383 }
2384
2385 #[test]
2386 #[should_panic(expected = "CiphertextFailedVerification")]
2387 fn test_publicasymmetrickey_unseal_with_invalid_nonce() {
2388 let (sopak, sosak) = get_sopak();
2389 let ciphertext = get_sopak_ciphertext(b"hello, world!", None);
2390 let _ = sopak
2391 .unseal(
2392 &ciphertext.as_slice().into(),
2393 &sosak,
2394 &SodiumOxideAsymmetricNonce {
2395 nonce: box_::gen_nonce(),
2396 },
2397 )
2398 .unwrap();
2399 }
2400
2401 #[test]
2402 fn test_publicasymmetrickey_to_index() {
2403 let index = SodiumOxideCurve25519PublicAsymmetricKey::get_index();
2404 assert_eq!(
2405 index,
2406 Some(bson::doc! {
2407 "c": {
2408 "builder": {
2409 "t": "Key",
2410 "c": {
2411 "t": "Asymmetric",
2412 "c": {
2413 "t": "Public",
2414 "c": {
2415 "t": "SodiumOxideCurve25519"
2416 }
2417 }
2418 }
2419 }
2420 }
2421 })
2422 )
2423 }
2424
2425 #[test]
2426 fn test_publicasymmetrickey_to_builder() {
2427 let (sopak, _) = SodiumOxideCurve25519PublicAsymmetricKey::new();
2428 let builder = sopak.builder();
2429 let key_bytes = sopak.public_key.as_ref();
2430 let built_key = builder.build(Some(key_bytes)).unwrap();
2431 assert_eq!(built_key.public_key.as_ref(), sopak.public_key.as_ref());
2432 }
2433
2434 #[test]
2435 fn test_publicasymmetrickey_new() {
2436 let (sopak, _) = SodiumOxideCurve25519PublicAsymmetricKey::new();
2437 assert!(!sopak.public_key.as_ref().is_empty());
2438 }
2439}