1use std::any::Any;
2use std::io::{IoSlice, IoSliceMut};
3use std::sync::Arc;
4
5use digest::generic_array::ArrayLength;
6use digest::Digest;
7use ecdsa::elliptic_curve::ops::{Invert, Reduce};
8use ecdsa::elliptic_curve::subtle::CtOption;
9use ecdsa::elliptic_curve::{ProjectiveArithmetic, Scalar};
10use ecdsa::hazmat::SignPrimitive;
11use ecdsa::{PrimeCurve, SignatureSize};
12use rsa::PublicKeyParts;
13use sha2::{Sha256, Sha384, Sha512};
14use signature::{DigestVerifier, RandomizedDigestSigner, Signature};
15use uuid::Uuid;
16use wasi_common::file::{FdFlags, FileType, Filestat, RiFlags, RoFlags, SiFlags};
17use wasi_common::{Error, ErrorExt, ErrorKind, WasiDir, WasiFile};
18use wasmtime_vfs_dir::Directory;
19use wasmtime_vfs_ledger::InodeId;
20use wasmtime_vfs_memory::{Data, Inode, Link, Node};
21
22use crate::share::Share;
23use crate::sign::Sign;
24use crate::verify::Verify;
25use crate::{ES256, ES256K, ES384, PS256, PS384, PS512, RS256, RS384, RS512};
26
27type Rs256 = rsa::pkcs1v15::SigningKey<Sha256>;
28type Rs384 = rsa::pkcs1v15::SigningKey<Sha384>;
29type Rs512 = rsa::pkcs1v15::SigningKey<Sha512>;
30type Ps256 = rsa::pss::BlindedSigningKey<Sha256>;
31type Ps384 = rsa::pss::BlindedSigningKey<Sha384>;
32type Ps512 = rsa::pss::BlindedSigningKey<Sha512>;
33type Es256k = ecdsa::SigningKey<k256::Secp256k1>;
34type Es256 = ecdsa::SigningKey<p256::NistP256>;
35type Es384 = ecdsa::SigningKey<p384::NistP384>;
36
37trait GenerateKey: Sized {
38 fn generate() -> Result<Self, Error>;
39}
40
41impl GenerateKey for Rs256 {
42 fn generate() -> Result<Self, Error> {
43 Ok(rsa::RsaPrivateKey::new(&mut rand::thread_rng(), 2048)?.into())
44 }
45}
46
47impl GenerateKey for Rs384 {
48 fn generate() -> Result<Self, Error> {
49 Ok(rsa::RsaPrivateKey::new(&mut rand::thread_rng(), 3072)?.into())
50 }
51}
52
53impl GenerateKey for Rs512 {
54 fn generate() -> Result<Self, Error> {
55 Ok(rsa::RsaPrivateKey::new(&mut rand::thread_rng(), 4096)?.into())
56 }
57}
58
59impl GenerateKey for Ps256 {
60 fn generate() -> Result<Self, Error> {
61 Ok(rsa::RsaPrivateKey::new(&mut rand::thread_rng(), 2048)?.into())
62 }
63}
64
65impl GenerateKey for Ps384 {
66 fn generate() -> Result<Self, Error> {
67 Ok(rsa::RsaPrivateKey::new(&mut rand::thread_rng(), 3072)?.into())
68 }
69}
70
71impl GenerateKey for Ps512 {
72 fn generate() -> Result<Self, Error> {
73 Ok(rsa::RsaPrivateKey::new(&mut rand::thread_rng(), 4096)?.into())
74 }
75}
76
77impl GenerateKey for Es256k {
78 fn generate() -> Result<Self, Error> {
79 Ok(ecdsa::SigningKey::random(&mut rand::thread_rng()))
80 }
81}
82
83impl GenerateKey for Es256 {
84 fn generate() -> Result<Self, Error> {
85 Ok(ecdsa::SigningKey::random(&mut rand::thread_rng()))
86 }
87}
88
89impl GenerateKey for Es384 {
90 fn generate() -> Result<Self, Error> {
91 Ok(ecdsa::SigningKey::random(&mut rand::thread_rng()))
92 }
93}
94
95trait ToPublic {
96 type Public;
97
98 fn to_public(&self) -> Self::Public;
99}
100
101impl<D: Digest> ToPublic for rsa::pkcs1v15::SigningKey<D> {
102 type Public = rsa::pkcs1v15::VerifyingKey<D>;
103
104 fn to_public(&self) -> Self::Public {
105 Self::Public::from(self)
106 }
107}
108
109impl<D: Digest> ToPublic for rsa::pss::BlindedSigningKey<D> {
110 type Public = rsa::pss::VerifyingKey<D>;
111
112 fn to_public(&self) -> Self::Public {
113 Self::Public::from(self)
114 }
115}
116
117impl<C: ecdsa::elliptic_curve::Curve> ToPublic for ecdsa::SigningKey<C>
118where
119 C: PrimeCurve + ProjectiveArithmetic,
120 Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + Reduce<C::UInt> + SignPrimitive<C>,
121 SignatureSize<C>: ArrayLength<u8>,
122{
123 type Public = ecdsa::VerifyingKey<C>;
124
125 fn to_public(&self) -> Self::Public {
126 Self::Public::from(self)
127 }
128}
129
130trait Encoder<T> {
131 fn encode(&self, arg: T) -> Result<Vec<u8>, Error>;
132}
133
134impl Encoder<&[u8]> for rsa::RsaPublicKey {
135 fn encode(&self, prefix: &[u8]) -> Result<Vec<u8>, Error> {
136 let e = self.e().to_bytes_be();
137 let n = self.n().to_bytes_be();
138
139 let el = u32::try_from(e.len()).map_err(|_| Error::io())?;
140 let nl = u32::try_from(n.len()).map_err(|_| Error::io())?;
141
142 let mut out = prefix.to_vec();
143 out.extend_from_slice(&el.to_be_bytes());
144 out.extend_from_slice(&e);
145 out.extend_from_slice(&nl.to_be_bytes());
146 out.extend_from_slice(&n);
147
148 Ok(out)
149 }
150}
151
152impl Encoder<()> for rsa::pkcs1v15::VerifyingKey<Sha256> {
153 fn encode(&self, _: ()) -> Result<Vec<u8>, Error> {
154 self.as_ref().encode(RS256)
155 }
156}
157
158impl Encoder<()> for rsa::pkcs1v15::VerifyingKey<Sha384> {
159 fn encode(&self, _: ()) -> Result<Vec<u8>, Error> {
160 self.as_ref().encode(RS384)
161 }
162}
163
164impl Encoder<()> for rsa::pkcs1v15::VerifyingKey<Sha512> {
165 fn encode(&self, _: ()) -> Result<Vec<u8>, Error> {
166 self.as_ref().encode(RS512)
167 }
168}
169
170impl Encoder<()> for rsa::pss::VerifyingKey<Sha256> {
171 fn encode(&self, _: ()) -> Result<Vec<u8>, Error> {
172 self.as_ref().encode(PS256)
173 }
174}
175
176impl Encoder<()> for rsa::pss::VerifyingKey<Sha384> {
177 fn encode(&self, _: ()) -> Result<Vec<u8>, Error> {
178 self.as_ref().encode(PS384)
179 }
180}
181
182impl Encoder<()> for rsa::pss::VerifyingKey<Sha512> {
183 fn encode(&self, _: ()) -> Result<Vec<u8>, Error> {
184 self.as_ref().encode(PS512)
185 }
186}
187
188impl Encoder<()> for ecdsa::VerifyingKey<k256::Secp256k1> {
189 fn encode(&self, _: ()) -> Result<Vec<u8>, Error> {
190 let mut out = ES256K.to_vec();
191 out.extend_from_slice(self.to_encoded_point(false).as_bytes());
192 Ok(out)
193 }
194}
195
196impl Encoder<()> for ecdsa::VerifyingKey<p256::NistP256> {
197 fn encode(&self, _: ()) -> Result<Vec<u8>, Error> {
198 let mut out = ES256.to_vec();
199 out.extend_from_slice(self.to_encoded_point(false).as_bytes());
200 Ok(out)
201 }
202}
203
204impl Encoder<()> for ecdsa::VerifyingKey<p384::NistP384> {
205 fn encode(&self, _: ()) -> Result<Vec<u8>, Error> {
206 let mut out = ES384.to_vec();
207 out.extend_from_slice(self.to_encoded_point(false).as_bytes());
208 Ok(out)
209 }
210}
211
212pub struct Generate(Link<Vec<Uuid>>);
213
214#[async_trait::async_trait]
215impl Node for Generate {
216 fn to_any(self: Arc<Self>) -> Arc<dyn Any + Send + Sync> {
217 self
218 }
219
220 fn parent(&self) -> Option<Arc<dyn Node>> {
221 self.0.parent.upgrade()
222 }
223
224 fn filetype(&self) -> FileType {
225 FileType::SocketDgram
226 }
227
228 fn id(&self) -> Arc<InodeId> {
229 self.0.inode.id.clone()
230 }
231
232 async fn open_dir(self: Arc<Self>) -> Result<Box<dyn WasiDir>, Error> {
233 Err(Error::not_dir())
234 }
235
236 async fn open_file(
237 self: Arc<Self>,
238 _path: &str,
239 dir: bool,
240 read: bool,
241 write: bool,
242 flags: FdFlags,
243 ) -> Result<Box<dyn WasiFile>, Error> {
244 if dir {
245 return Err(Error::not_dir());
246 }
247
248 if !read || !write {
249 return Err(Error::perm()); }
251
252 if !flags.is_empty() {
253 return Err(Error::invalid_argument()); }
255
256 Ok(Box::new(OpenGenerate {
257 _root: self.root(),
258 link: self,
259 }))
260 }
261}
262
263impl Generate {
264 pub fn new(parent: Arc<dyn Node>) -> Arc<Self> {
265 let id = parent.id().device().create_inode();
266
267 let inode = Inode {
268 data: Data::from(Vec::new()).into(),
269 id,
270 };
271
272 Arc::new(Self(Link {
273 parent: Arc::downgrade(&parent),
274 inode: inode.into(),
275 }))
276 }
277
278 async fn add<T, U, D, S>(self: &Arc<Generate>) -> Result<Uuid, Error>
279 where
280 T: Send + Sync + 'static,
281 U: Send + Sync + 'static,
282 D: Send + Sync + 'static,
283 S: Send + Sync + 'static,
284 T: RandomizedDigestSigner<D, S> + GenerateKey + ToPublic<Public = U>,
285 U: DigestVerifier<D, S> + Encoder<()>,
286 D: Digest + Clone,
287 S: Signature,
288 {
289 let parent = self
290 .parent()
291 .ok_or_else(Error::io)?
292 .to_any()
293 .downcast::<Directory>()
294 .map_err(|_| Error::io())?;
295
296 let secret = T::generate()?;
297 let public = secret.to_public();
298 let shared = public.encode(())?;
299 let uuid = uuid::Uuid::new_v4();
300
301 let d = Directory::new(parent.clone(), None);
302 d.attach("verify", Verify::new(d.clone(), public)).await?;
303 d.attach("share", Share::new(d.clone(), shared)).await?;
304 d.attach("sign", Sign::new(d.clone(), secret)).await?;
305 parent.attach(&uuid.to_string(), d).await?;
306
307 Ok(uuid)
308 }
309}
310
311struct OpenGenerate {
312 _root: Arc<dyn Node>,
313 link: Arc<Generate>,
314}
315
316#[async_trait::async_trait]
317impl WasiFile for OpenGenerate {
318 fn as_any(&self) -> &dyn Any {
319 self
320 }
321
322 async fn get_filetype(&mut self) -> Result<FileType, Error> {
323 Ok(FileType::SocketDgram)
324 }
325
326 async fn get_filestat(&mut self) -> Result<Filestat, Error> {
327 let ilock = self.link.0.inode.data.read().await;
328
329 Ok(Filestat {
330 device_id: **self.link.0.inode.id.device(),
331 inode: **self.link.0.inode.id,
332 filetype: FileType::SocketDgram,
333 nlink: Arc::strong_count(&self.link.0.inode) as u64,
334 size: 0,
335 atim: Some(ilock.access),
336 mtim: Some(ilock.modify),
337 ctim: Some(ilock.create),
338 })
339 }
340
341 async fn sock_recv<'a>(
342 &mut self,
343 bufs: &mut [IoSliceMut<'a>],
344 _flags: RiFlags,
345 ) -> Result<(u64, RoFlags), Error> {
346 let n = self.read_vectored(bufs).await?;
347 Ok((n, RoFlags::empty()))
348 }
349
350 async fn sock_send<'a>(&mut self, bufs: &[IoSlice<'a>], _flags: SiFlags) -> Result<u64, Error> {
351 self.write_vectored(bufs).await
352 }
353
354 async fn read_vectored<'a>(&mut self, bufs: &mut [IoSliceMut<'a>]) -> Result<u64, Error> {
355 let mut ilock = self.link.0.inode.data.write().await;
356
357 if let Some(uuid) = ilock.content.pop() {
358 let name = uuid.to_string();
359 let bytes = name.as_bytes();
360 let mut total = 0;
361
362 for buf in bufs {
363 let len = std::cmp::min(buf.len(), bytes.len() - total);
364 buf[..len].copy_from_slice(&bytes[total..][..len]);
365 total += len;
366 }
367
368 if total < bytes.len() {
369 ilock.content.push(uuid);
370 return Err(Error::too_big());
371 }
372
373 return Ok(total as u64);
374 }
375
376 Err(ErrorKind::WouldBlk.into())
377 }
378
379 async fn write_vectored<'a>(&mut self, bufs: &[IoSlice<'a>]) -> Result<u64, Error> {
380 if bufs.len() != 1 || bufs[0].len() != 4 {
381 return Err(Error::invalid_argument());
382 }
383
384 let uuid = match bufs[0].as_ref() {
385 RS256 => self.link.add::<Rs256, _, _, _>().await?,
386 RS384 => self.link.add::<Rs384, _, _, _>().await?,
387 RS512 => self.link.add::<Rs512, _, _, _>().await?,
388 PS256 => self.link.add::<Ps256, _, _, _>().await?,
389 PS384 => self.link.add::<Ps384, _, _, _>().await?,
390 PS512 => self.link.add::<Ps512, _, _, _>().await?,
391 ES256K => self.link.add::<Es256k, _, Sha256, _>().await?,
392 ES256 => self.link.add::<Es256, _, Sha256, _>().await?,
393 ES384 => self.link.add::<Es384, _, Sha384, _>().await?,
394 _ => return Err(ErrorKind::Ilseq.into()),
395 };
396
397 self.link.0.inode.data.write().await.content.push(uuid);
398 Ok(4)
399 }
400
401 async fn readable(&self) -> Result<(), Error> {
402 Ok(())
403 }
404
405 async fn writable(&self) -> Result<(), Error> {
406 Ok(())
407 }
408}