viceroy_lib/wiggle_abi/
secret_store_impl.rs1use {
2 crate::{
3 error::Error,
4 secret_store::SecretLookup,
5 session::Session,
6 wiggle_abi::{
7 fastly_secret_store::FastlySecretStore,
8 types::{FastlyStatus, SecretHandle, SecretStoreHandle},
9 },
10 },
11 std::convert::TryFrom,
12 wiggle::{GuestMemory, GuestPtr},
13};
14
15#[derive(Debug, thiserror::Error)]
16pub enum SecretStoreError {
17 #[error("Unknown secret store: {0}")]
19 UnknownSecretStore(String),
20
21 #[error("Unknown secret: {0}")]
23 UnknownSecret(String),
24
25 #[error("Invalid secret store handle: {0}")]
27 InvalidSecretStoreHandle(SecretStoreHandle),
28
29 #[error("Invalid secret handle: {0}")]
31 InvalidSecretHandle(SecretHandle),
32}
33
34impl From<&SecretStoreError> for FastlyStatus {
35 fn from(err: &SecretStoreError) -> Self {
36 use SecretStoreError::*;
37 match err {
38 UnknownSecretStore(_) => FastlyStatus::None,
39 UnknownSecret(_) => FastlyStatus::None,
40 InvalidSecretStoreHandle(_) => FastlyStatus::Badf,
41 InvalidSecretHandle(_) => FastlyStatus::Badf,
42 }
43 }
44}
45
46#[wiggle::async_trait]
47impl FastlySecretStore for Session {
48 fn open(
49 &mut self,
50 memory: &mut GuestMemory<'_>,
51 name: GuestPtr<str>,
52 ) -> Result<SecretStoreHandle, Error> {
53 let name = memory.as_str(name)?.ok_or(Error::SharedMemory)?;
54 self.secret_store_handle(&name)
55 .ok_or(Error::SecretStoreError(
56 SecretStoreError::UnknownSecretStore(name.to_string()),
57 ))
58 }
59
60 fn get(
61 &mut self,
62 memory: &mut GuestMemory<'_>,
63 secret_store_handle: SecretStoreHandle,
64 secret_name: GuestPtr<str>,
65 ) -> Result<SecretHandle, Error> {
66 let store_name =
67 self.secret_store_name(secret_store_handle)
68 .ok_or(Error::SecretStoreError(
69 SecretStoreError::InvalidSecretStoreHandle(secret_store_handle),
70 ))?;
71 let secret_name = memory.as_str(secret_name)?.ok_or(Error::SharedMemory)?;
72 self.secret_handle(store_name.as_str(), &secret_name)
73 .ok_or(Error::SecretStoreError(SecretStoreError::UnknownSecret(
74 secret_name.to_string(),
75 )))
76 }
77
78 fn plaintext(
79 &mut self,
80 memory: &mut GuestMemory<'_>,
81 secret_handle: SecretHandle,
82 plaintext_buf: GuestPtr<u8>,
83 plaintext_max_len: u32,
84 nwritten_out: GuestPtr<u32>,
85 ) -> Result<(), Error> {
86 let lookup = self
87 .secret_lookup(secret_handle)
88 .ok_or(Error::SecretStoreError(
89 SecretStoreError::InvalidSecretHandle(secret_handle),
90 ))?;
91
92 let plaintext = match &lookup {
93 SecretLookup::Standard {
94 store_name,
95 secret_name,
96 } => self
97 .secret_stores()
98 .get_store(store_name)
99 .ok_or(Error::SecretStoreError(
100 SecretStoreError::InvalidSecretHandle(secret_handle),
101 ))?
102 .get_secret(secret_name)
103 .ok_or(Error::SecretStoreError(
104 SecretStoreError::InvalidSecretHandle(secret_handle),
105 ))?
106 .plaintext(),
107
108 SecretLookup::Injected { plaintext } => plaintext,
109 };
110
111 if plaintext.len() > plaintext_max_len as usize {
112 memory.write(nwritten_out, plaintext.len() as u32)?;
116 return Err(Error::BufferLengthError {
117 buf: "plaintext_buf",
118 len: "plaintext_max_len",
119 });
120 }
121 let plaintext_len = u32::try_from(plaintext.len())
122 .expect("smaller than plaintext_max_len means it must fit");
123
124 memory.copy_from_slice(plaintext, plaintext_buf.as_array(plaintext_len))?;
125 memory.write(nwritten_out, plaintext_len)?;
126
127 Ok(())
128 }
129
130 fn from_bytes(
131 &mut self,
132 memory: &mut GuestMemory<'_>,
133 plaintext_buf: GuestPtr<u8>,
134 plaintext_len: u32,
135 ) -> Result<SecretHandle, Error> {
136 let plaintext = memory.to_vec(plaintext_buf.as_array(plaintext_len))?;
137 Ok(self.add_secret(plaintext))
138 }
139}