Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

features: support native signature client #1

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: build
args: --all-features
args: --features default

- name: Run cargo test with root privilege
run: |
sudo -E PATH=$PATH -s cargo test --all --all-features
sudo -E PATH=$PATH -s cargo test --all --features default

- name: Run cargo fmt check
uses: actions-rs/cargo@v1
Expand Down
60 changes: 60 additions & 0 deletions .github/workflows/ci_eaa_kbc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: image-rs eaa_kbc build
on:
pull_request:
paths:
- 'signature/**'

jobs:
ci:
if: github.event_name == 'pull_request' || github.event_name == 'push'
name: Check
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
rust:
- stable
- beta
- nightly
# Run all steps in the compilation testing containers
container:
image: runetest/compilation-testing:ubuntu18.04
env:
LD_LIBRARY_PATH: /usr/local/lib/rats-tls

steps:
- name: Update cargo home
run: |
apt-get update && apt-get install -y cargo
cp -r /root/.cargo /github/home/.cargo

- name: Install Rust toolchain (${{ matrix.rust }})
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: ${{ matrix.rust }}
override: true
components: rustfmt, clippy

- name: Install nettle-sys building dependence
run: |
apt-get install -y clang llvm pkg-config nettle-dev protobuf-compiler libprotobuf-dev

- name: Build and install rats-tls
run: |
apt-get install -y libcurl4-openssl-dev
git clone https://github.com/inclavare-containers/rats-tls
cd rats-tls
cmake -DBUILD_SAMPLES=on -H. -Bbuild
make -C build install

- name: Code checkout
uses: actions/checkout@v2
with:
fetch-depth: 1

- name: Run cargo build
uses: actions-rs/cargo@v1
with:
command: build
args: --features occlum_feature
11 changes: 5 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ libc = "0.2"
nix = "0.23.0"
oci-distribution = "0.9.3"
oci-spec = { git = "https://github.com/containers/oci-spec-rs" }
ocicrypt-rs = { git = "https://github.com/confidential-containers/ocicrypt-rs", tag = "v0.2.0" }
ocicrypt-rs = { git = "https://github.com/confidential-containers/ocicrypt-rs", tag = "v0.2.0", optional = true }

serde = { version = ">=1.0.27", features = ["serde_derive", "rc"] }
serde_json = ">=1.0.9"
sha2 = ">=0.10"
Expand All @@ -26,7 +27,7 @@ zstd = "0.9"
fs_extra = "1.2.0"
walkdir = "2"
dircpy = "0.3.12"
signature = { path = "./signature" }
signature = { path = "./signature", optional = true }
prost = "0.8"
strum = { version = "0.23.0", features = ["derive"] }
log = "0.4.14"
Expand All @@ -45,8 +46,6 @@ members = ["signature", "libs/test-utils"]
exclude = ["scripts/attestation_agent/app"]

[features]
default = ["overlay_feature"]
default = ["overlay_feature", "ocicrypt-rs", "signature"]
overlay_feature = []
occlum_feature = []

[build-dependencies]
occlum_feature = ["ocicrypt-rs/eaa_kbc", "signature/eaa_kbc"]
6 changes: 6 additions & 0 deletions signature/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ tonic = "0.5"
prost = "0.8"
strum_macros = "0.24.2"
sigstore_rs = { git = "https://github.com/sigstore/sigstore-rs", rev = "6dd3281c25270f0d82550368abfb399ed3da7b41", package = "sigstore" }
ocicrypt-rs = { git = "https://github.com/confidential-containers/ocicrypt-rs", optional = true }
attestation_agent = { git = "https://github.com/confidential-containers/attestation-agent", rev = "3b4716dd3d8bbf0d5f8cec7bc0d528421f00fd06", optional = true }

[build-dependencies]
tonic-build = "0.5"
Expand All @@ -28,3 +30,7 @@ shadow-rs = "0.17.1"
[dev-dependencies]
rstest = "0.15.0"
serial_test = "0.9.0"

[features]
default = ["attestation_agent/default", "ocicrypt-rs/default"]
eaa_kbc = ["attestation_agent/eaa_kbc", "ocicrypt-rs/eaa_kbc"]
91 changes: 75 additions & 16 deletions signature/src/agent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@
use std::{collections::HashMap, path::Path};

use anyhow::*;
use attestation_agent::AttestationAPIs;
use attestation_agent::AttestationAgent;
use oci_distribution::Reference;
use ocicrypt_rs::config::{OcicryptConfig, OCICRYPT_ENVVARNAME};
use serde::{Deserialize, Serialize};
use std::result::Result::Ok;
use tokio::fs;
use tonic::transport::Channel;

Expand Down Expand Up @@ -35,13 +39,49 @@ pub const POLICY_FILE_PATH: &str = "/run/image-security/security_policy.json";
/// Attestation Agent's GetResource gRPC address.
/// It's given <https://github.com/confidential-containers/attestation-agent#run>
pub const AA_GETRESOURCE_ADDR: &str = "http://127.0.0.1:50001";
/// The native attestation agent's name.
/// It's given <https://github.com/confidential-containers/attestation-agent>
pub const NATIVE_AA_NAME: &str = "attestation-agent";

/// Signature submodule agent for image signature veriication.
/// Signature submodule agent for image signature verification.
pub struct Agent {
/// Get Resource Service client.
client: GetResourceServiceClient<Channel>,
/// Get Resource Client
client: SigClient,
kbc_name: String,
kbc_uri: String,
kbs_uri: String,
}

// Types of the signature client
enum SigClient {
/// Get Resource Service gRPC client
ServiceGPRC(GetResourceServiceClient<Channel>),
/// Get Rserouce native AA client
NativeAA(AttestationAgent),
}

impl SigClient {
// get_resource retrieves verification resource
async fn get_resource(
&mut self,
kbc_name: String,
kbs_uri: String,
resource_description: String,
) -> Result<Vec<u8>> {
match self {
Self::ServiceGPRC(client) => {
let req = tonic::Request::new(GetResourceRequest {
kbc_name,
kbs_uri,
resource_description,
});
Ok(client.get_resource(req).await?.into_inner().resource)
}
Self::NativeAA(aa) => {
aa.download_confidential_resource(kbc_name, kbs_uri, resource_description)
.await
}
}
}
}

/// The resource description that will be passed to AA when get resource.
Expand Down Expand Up @@ -70,15 +110,19 @@ impl Agent {
if kbc_name.is_empty() {
return Err(anyhow!("aa_kbc_params: missing KBC name"));
}

if kbs_uri.is_empty() {
return Err(anyhow!("aa_kbc_params: missing KBS URI"));
}

Ok(Self {
client: GetResourceServiceClient::connect(AA_GETRESOURCE_ADDR).await?,
client: if is_native_aa() {
SigClient::NativeAA(AttestationAgent::new())
} else {
SigClient::ServiceGPRC(
GetResourceServiceClient::connect(AA_GETRESOURCE_ADDR).await?,
)
},
kbs_uri: kbs_uri.into(),
kbc_name: kbc_name.into(),
kbc_uri: kbs_uri.into(),
})
} else {
Err(anyhow!("aa_kbc_params: KBC/KBS pair not found"))
Expand All @@ -91,14 +135,15 @@ impl Agent {
/// Then save the gathered data into `path`
async fn get_resource(&mut self, resource_name: &str, path: &str) -> Result<()> {
let resource_description = serde_json::to_string(&ResourceDescription::new(resource_name))?;
let req = tonic::Request::new(GetResourceRequest {
kbc_name: self.kbc_name.clone(),
kbs_uri: self.kbc_uri.clone(),
resource_description,
});
let res = self.client.get_resource(req).await?;

fs::write(path, res.into_inner().resource).await?;
let res = self
.client
.get_resource(
self.kbc_name.clone(),
self.kbs_uri.clone(),
resource_description,
)
.await?;
fs::write(path, res).await?;
Ok(())
}

Expand Down Expand Up @@ -144,3 +189,17 @@ impl Agent {
.map_err(|e| anyhow!("Validate image failed: {:?}", e))
}
}

fn is_native_aa() -> bool {
let ocicrypt_config = match OcicryptConfig::from_env(OCICRYPT_ENVVARNAME) {
Ok(oc) => oc,
Err(_) => return false,
};
let key_providers = ocicrypt_config.key_providers;
for (provider_name, attrs) in key_providers.iter() {
if provider_name == NATIVE_AA_NAME && attrs.native.is_some() {
return true;
}
}
false
}
1 change: 0 additions & 1 deletion src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ impl Default for ImageConfig {
let work_dir = PathBuf::from(
std::env::var(CC_IMAGE_WORK_DIR).unwrap_or_else(|_| DEFAULT_WORK_DIR.to_string()),
);

ImageConfig {
work_dir,
default_snapshot: SnapshotType::Overlay,
Expand Down