Skip to content

Commit

Permalink
Use randomly generated key in image-rs to secure image layers in sefs
Browse files Browse the repository at this point in the history
Signed-off-by: piotrpalcz <[email protected]>
  • Loading branch information
piotrpalcz committed Dec 19, 2023
1 parent a447133 commit 65fe440
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 56 deletions.
9 changes: 9 additions & 0 deletions image-rs/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"rust-analyzer.linkedProjects": [
"./Cargo.toml",
"./Cargo.toml",
"./Cargo.toml",
"./Cargo.toml",
"./Cargo.toml"
]
}
1 change: 0 additions & 1 deletion image-rs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ oci-spec = "0.6.2"
ocicrypt-rs = { path = "../ocicrypt-rs", default-features = false, features = ["async-io"], optional = true }
prost = { workspace = true, optional = true }
protobuf = { workspace = true, optional = true }
rand = "0.8.5"
reqwest = { workspace = true, features = ["json"], optional = true }
sequoia-openpgp = { version = "1.7.0", default-features = false, features = ["compression", "crypto-rust", "allow-experimental-crypto", "allow-variable-time-crypto"], optional = true }
serde = { workspace = true, features = ["serde_derive", "rc"] }
Expand Down
114 changes: 59 additions & 55 deletions image-rs/src/snapshots/occlum/unionfs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,16 @@
// This unionfs file is used for occlum only

use std::fs;
use std::fs::{File, OpenOptions};
use std::io::{Error, ErrorKind, self, Write};
use std::fs::File;
use std::io::Write;
use std::path::{Path, PathBuf};
use std::sync::atomic::AtomicUsize;
use std::ffi::CString;

use anyhow::{anyhow, Context, Result};
use dircpy::CopyBuilder;
use fs_extra;
use fs_extra::dir;
use nix::mount::MsFlags;
use rand::Rng;

use ocicrypt_rs::blockcipher::rand::rand_bytes;

Expand Down Expand Up @@ -53,28 +51,31 @@ fn create_dir(create_path: &Path) -> Result<()> {
Ok(())
}

fn create_key_file(path: &PathBuf, key: &str) -> Result<()> {
let mut file = File::create(path)
.with_context(|| format!("Failed to create file: {:?}", path))?;

file.write_all(key.as_bytes())
.with_context(|| format!("Failed to write to file: {:?}", path))?;

Ok(())

}
// returns randomly generted random 128 bit key
fn generate_random_key() -> String {

let mut key: [u8; 16] = [0u8; 16];

rand_bytes(&mut key).expect("Random fill failed");

let formatted_key = key.iter().map(|byte| format!("{:02x}", byte)).collect::<Vec<String>>().join("-");
let formatted_key = key
.iter()
.map(|byte| format!("{:02x}", byte))
.collect::<Vec<String>>()
.join("-");

formatted_key
}

fn create_key_file(path: &PathBuf, key: &str) -> Result<()> {
let mut file =
File::create(path).with_context(|| format!("Failed to create file: {:?}", path))?;

file.write_all(key.as_bytes())
.with_context(|| format!("Failed to write to file: {:?}", path))?;

Ok(())
}

fn create_environment(mount_path: &Path) -> Result<()> {
let mut from_paths = Vec::new();
let mut copy_options = dir::CopyOptions::new();
Expand All @@ -97,7 +98,6 @@ fn create_environment(mount_path: &Path) -> Result<()> {
if fs::symlink_metadata(ld_lib.as_path()).is_ok() {
fs::remove_file(ld_lib)?;
}

fs_extra::copy_items(&from_paths, &path_lib64, &copy_options)?;
from_paths.clear();

Expand Down Expand Up @@ -138,10 +138,9 @@ fn create_environment(mount_path: &Path) -> Result<()> {

impl Snapshotter for Unionfs {
fn mount(&mut self, layer_path: &[&str], mount_path: &Path) -> Result<MountPoint> {
// From the description of https://github.com/occlum/occlum/blob/master/docs/runtime_mount.md#1-mount-trusted-unionfs-consisting-of-sefss ,
// the source type of runtime mount is "unionfs".
let fs_type = String::from("sefs");
let source = Path::new(&fs_type);
let flags = MsFlags::empty();

if !mount_path.exists() {
fs::create_dir_all(mount_path)?;
Expand All @@ -154,17 +153,53 @@ impl Snapshotter for Unionfs {
.file_name()
.ok_or(anyhow!("Unknown error: file name parse fail"))?;

// For mounting trusted UnionFS at runtime of occlum,
// you can refer to https://github.com/occlum/occlum/blob/master/docs/runtime_mount.md#1-mount-trusted-unionfs-consisting-of-sefss.
let random_key = generate_random_key();
let new_key_path = Path::new("/new_key");
fs::create_dir_all(new_key_path)?;
create_key_file(&PathBuf::from(&new_key_path.join("key.txt")), &random_key).map_err(
|e| {
anyhow!(
"failed to write key file {:?} with error: {}",
"/key.txt",
e
)
},
)?;

let key_mount_options = format!(
"dir={}",
Path::new("/images")
.join(cid)
.join("keys/sefs/lower")
.display()
);

let keys_mount_path = Path::new("/keys");
nix::mount::mount(
Some(source),
keys_mount_path,
Some(fs_type.as_str()),
flags,
Some(key_mount_options.as_str()),
)
.map_err(|e| {
anyhow!(
"failed to mount {:?} to {:?}, with error: {}",
source,
keys_mount_path,
e
)
})?;

fs::copy("/new_key/key.txt", "/keys/key.txt")?;
nix::mount::umount(keys_mount_path)?;

let options = format!(
"dir={},key={}",
Path::new("/images").join(cid).join("sefs/lower").display(),
random_key
);

let flags = MsFlags::empty();

nix::mount::mount(
Some(source),
mount_path,
Expand Down Expand Up @@ -193,41 +228,10 @@ impl Snapshotter for Unionfs {
.ok_or(anyhow!("Pop() failed from Vec"))?;
CopyBuilder::new(layer, mount_path).overwrite(true).run()?;
}

let sealing_keys_dir = Path::new("/keys").join(cid).join("keys");
fs::create_dir_all(sealing_keys_dir.clone())?;
let key_file_create_path = sealing_keys_dir.join("key.txt");

create_key_file(&PathBuf::from(&key_file_create_path), &random_key)
.map_err(|e| {
anyhow!(
"failed to write key file {:?} with error: {}",
key_file_create_path,
e
)
})?;

let hostfs_fstype = String::from("hostfs");
let keys_mount_path = Path::new("/keys");

let mountpoint_c = CString::new(keys_mount_path.to_str().unwrap()).unwrap();
nix::mount::mount(
Some(hostfs_fstype.as_str()),
mountpoint_c.as_c_str(),
Some(hostfs_fstype.as_str()),
flags,
Some("dir=/keys"),
).map_err(|e| {
anyhow!(
"failed to mount {:?} to {:?}, with error: {}",
hostfs_fstype.as_str(),
keys_mount_path,
e
)
})?;

// create environment for Occlum
create_environment(mount_path)?;

nix::mount::umount(mount_path)?;

Ok(MountPoint {
Expand Down

0 comments on commit 65fe440

Please sign in to comment.