haste_encryption/traits.rs
1use haste_fhir_operation_error::OperationOutcomeError;
2use std::{future::Future, pin::Pin};
3
4/// A secret's raw byte value. `Debug` is redacted so the value never
5/// ends up in logs or error messages by accident.
6pub struct Secret(Vec<u8>);
7
8impl Secret {
9 #[must_use]
10 pub fn new(bytes: Vec<u8>) -> Self {
11 Self(bytes)
12 }
13
14 #[must_use]
15 pub fn expose_bytes(&self) -> &[u8] {
16 &self.0
17 }
18}
19
20impl std::fmt::Debug for Secret {
21 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
22 f.write_str("Secret(REDACTED)")
23 }
24}
25
26/// Retrieves secret material (encryption keys, credentials, etc.) by name
27/// from a backing store, e.g. AWS Secrets Manager, GCP Secret Manager, or
28/// environment variables.
29pub trait SecretsProvider: Sync + Send {
30 fn get_secret<'a>(
31 &'a self,
32 name: &'a str,
33 ) -> Pin<Box<dyn Future<Output = Result<Secret, OperationOutcomeError>> + Send + 'a>>;
34}
35
36pub struct EncryptionResult {
37 pub nonce: Vec<u8>,
38 pub ciphertext: Vec<u8>,
39}
40
41/// Provides symmetric authenticated encryption and decryption of arbitrary
42/// byte payloads.
43///
44/// Implementations are expected to encrypt data in a way that ensures both
45/// confidentiality and integrity. A value returned by [`Self::encrypt`]
46/// should be decryptable only by the same implementation initialized with the
47/// same keying material.
48pub trait Encryptor: Sync + Send {
49 /// Encrypts the given plaintext.
50 ///
51 /// # Errors
52 ///
53 /// Returns an [`OperationOutcomeError`] if the plaintext cannot be
54 /// encrypted.
55 fn encrypt(&self, plaintext: &[u8]) -> Result<EncryptionResult, OperationOutcomeError>;
56 /// Decrypts a previously encrypted payload.
57 ///
58 /// # Errors
59 ///
60 /// Returns an [`OperationOutcomeError`] if the ciphertext is invalid,
61 /// has been tampered with, or cannot be decrypted.
62 fn decrypt(&self, ciphertext: &EncryptionResult) -> Result<Vec<u8>, OperationOutcomeError>;
63}