Преглед изворни кода

Started adding writecap request and approval.

Matthew Carr пре 2 година
родитељ
комит
dbe9632e8f
4 измењених фајлова са 84 додато и 14 уклоњено
  1. 2 2
      Cargo.lock
  2. 36 2
      crates/btlib/src/crypto/mod.rs
  3. 35 0
      crates/btlib/src/crypto/tpm.rs
  4. 11 10
      crates/btlib/src/test_helpers.rs

+ 2 - 2
Cargo.lock

@@ -191,9 +191,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 
 [[package]]
 name = "clang-sys"
-version = "1.3.3"
+version = "1.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a050e2153c5be08febd6734e29298e844fdb0fa21aeddd63b4eb7baa106c69b"
+checksum = "fa2e27ae6ab525c3d369ded447057bca5438d86dc3a68f6faafb8269ba82ebf3"
 dependencies = [
  "glob",
  "libc",

+ 36 - 2
crates/btlib/src/crypto/mod.rs

@@ -48,6 +48,22 @@ impl<T> Ciphertext<T> {
     }
 }
 
+pub struct Signed<T> {
+    data: Vec<u8>,
+    sig: Signature,
+    phantom: PhantomData<T>,
+}
+
+impl<T> Signed<T> {
+    pub fn new(data: Vec<u8>, sig: Signature) -> Signed<T> {
+        Signed {
+            data,
+            sig,
+            phantom: PhantomData,
+        }
+    }
+}
+
 /// Errors that can occur during cryptographic operations.
 #[derive(Debug)]
 pub enum Error {
@@ -1129,10 +1145,18 @@ pub(crate) trait Decrypter {
     fn decrypt(&self, slice: &[u8]) -> Result<Vec<u8>>;
 }
 
-pub(crate) trait Signer {
+pub trait Signer {
     fn sign<'a, I: Iterator<Item = &'a [u8]>>(&self, parts: I) -> Result<Signature>;
 }
 
+pub trait SignerExt: Signer {
+    fn ser_sign<T: Serialize>(&self, value: &T) -> Result<Signed<T>> {
+        let data = to_vec(value)?;
+        let sig = self.sign([data.as_slice()].into_iter())?;
+        Ok(Signed::new(data, sig))
+    }
+}
+
 pub(crate) trait Verifier {
     fn verify<'a, I: Iterator<Item = &'a [u8]>>(&self, parts: I, signature: &[u8]) -> Result<()>;
 }
@@ -1153,6 +1177,7 @@ pub(crate) trait Creds: CredsPriv + CredsPub {}
 pub(crate) trait CredStore {
     type CredHandle: Creds;
     type ExportedCreds: Serialize + for<'de> Deserialize<'de>;
+    type WritecapReq: Serialize + for<'de> Deserialize<'de> + AsRef<AsymKeyPub<Sign>>;
 
     /// Returns the node credentials. If credentials haven't been generated, they are generated
     /// stored and returned.
@@ -1175,6 +1200,15 @@ pub(crate) trait CredStore {
         password: &str,
         exported: Self::ExportedCreds,
     ) -> Result<Self::CredHandle>;
+    /// Creates a writecap request for the given `Principal`.
+    fn request_writecap(&self, root: Principal) -> Result<Self::WritecapReq>;
+    /// Issues a writecap for the given path to the node in the given request.
+    fn issue_writecap(
+        &self,
+        request: &Self::WritecapReq,
+        path: &Path,
+        password: &str,
+    ) -> Result<Writecap>;
 }
 
 /// Returns the base 2 logarithm of the given number. This function will return -1 when given 0, and
@@ -1185,7 +1219,7 @@ fn log2(mut n: usize) -> isize {
     if 0 == n {
         return -1;
     }
-    let num_bits = 8 * std::mem::size_of::<usize>() as isize;
+    let num_bits = usize::BITS.try_into().unwrap();
     for k in 0..num_bits {
         n >>= 1;
         if 0 == n {

+ 35 - 0
crates/btlib/src/crypto/tpm.rs

@@ -1100,9 +1100,28 @@ impl DerivationParams {
     }
 }
 
+#[derive(Serialize, Deserialize)]
+struct WritecapReqBody {
+    pub_key: AsymKeyPub<Sign>,
+    req_for: Principal,
+}
+
+#[derive(Serialize, Deserialize)]
+pub struct WritecapReq {
+    body: WritecapReqBody,
+    sig: Signature,
+}
+
+impl AsRef<AsymKeyPub<Sign>> for WritecapReq {
+    fn as_ref(&self) -> &AsymKeyPub<Sign> {
+        &self.body.pub_key
+    }
+}
+
 impl CredStore for TpmCredStore {
     type CredHandle = TpmCreds;
     type ExportedCreds = ExportedCreds;
+    type WritecapReq = WritecapReq;
 
     fn node_creds(&self) -> Result<TpmCreds> {
         {
@@ -1218,6 +1237,22 @@ impl CredStore for TpmCredStore {
         self.persist(&creds, |storage, handles| storage.root = Some(handles))?;
         Ok(creds)
     }
+
+    fn request_writecap(&self, req_for: Principal) -> Result<Self::WritecapReq> {
+        let node_creds = self.node_creds()?;
+        let pub_key = node_creds.public_sign().clone();
+        let body = WritecapReqBody { pub_key, req_for };
+        unimplemented!()
+    }
+
+    fn issue_writecap(
+        &self,
+        request: &Self::WritecapReq,
+        path: &crate::Path,
+        password: &str,
+    ) -> Result<Writecap> {
+        unimplemented!()
+    }
 }
 
 impl<S: Scheme> AsymKeyPub<S> {

+ 11 - 10
crates/btlib/src/test_helpers.rs

@@ -12,7 +12,7 @@ use std::{
     fs::File,
     io::{Cursor, Write},
     path::PathBuf,
-    process::{Command, ExitStatus, Stdio},
+    process::{Command, ExitStatus},
     str::FromStr,
     sync::atomic::{AtomicU16, Ordering},
 };
@@ -508,11 +508,13 @@ trait ExitStatusExt {
 
 impl ExitStatusExt for ExitStatus {
     fn success_or_err(&self) -> btserde::Result<()> {
-        match self.success() {
-            true => Ok(()),
-            false => Err(btserde::Error::Message(
-                "ExitCode was not successful".to_string(),
-            )),
+        match self.code() {
+            Some(0) => Ok(()),
+            Some(code) => Err(btserde::Error::Message(format!(
+                "ExitCode was non-zero: {}",
+                code
+            ))),
+            None => Err(btserde::Error::Message("ExitCode was None.".to_string())),
         }
     }
 }
@@ -531,7 +533,7 @@ impl SwtpmHarness {
         static PORT: AtomicU16 = AtomicU16::new(21901);
         let port = PORT.fetch_add(2, Ordering::SeqCst);
         let ctrl_port = port + 1;
-        let dir = TempDir::new(format!("btnode.{port}").as_str())?;
+        let dir = TempDir::new(format!("swtpm_harness.{port}").as_str())?;
         let dir_path = dir.path();
         let dir_path_display = dir_path.display();
         let conf_path = dir_path.join("swtpm_setup.conf");
@@ -541,7 +543,7 @@ impl SwtpmHarness {
         std::fs::write(
             &conf_path,
             r#"# Program invoked for creating certificates
-create_certs_tool= /usr/bin/swtpm_localca
+#create_certs_tool= /usr/bin/swtpm_localca
 # Comma-separated list (no spaces) of PCR banks to activate by default
 active_pcr_banks = sha256
 "#,
@@ -552,9 +554,8 @@ active_pcr_banks = sha256
                 "--config",
                 conf_path.to_str().unwrap(),
                 "--tpm-state",
-                format!("dir://{dir_path_display}").as_str(),
+                format!("{dir_path_display}").as_str(),
             ])
-            .stdout(Stdio::null())
             .status()?
             .success_or_err()?;
         Command::new("swtpm")