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

AA: kbs: Improve handling of invalid RCAR JSON #723

Merged
Merged
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
2 changes: 1 addition & 1 deletion attestation-agent/deps/crypto/src/algorithms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use std::fmt;
use std::str::FromStr;

/// Hash algorithms used to calculate runtime/init data binding
#[derive(Serialize, Deserialize, Clone, Debug, Display, Copy)]
#[derive(Serialize, Deserialize, Clone, Debug, Display, Copy, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum HashAlgorithm {
Sha256,
Expand Down
86 changes: 71 additions & 15 deletions attestation-agent/kbs_protocol/src/client/rcar_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,26 @@ async fn get_request_extra_params() -> serde_json::Value {
extra_params
}

fn get_hash_algorithm(extra_params: serde_json::Value) -> Result<HashAlgorithm> {
let algorithm = match extra_params.get(SELECTED_HASH_ALGORITHM_JSON_KEY) {
Some(selected_hash_algorithm) => {
let name = selected_hash_algorithm
.as_str()
.ok_or(Error::UnexpectedJSONDataType(
"string".into(),
selected_hash_algorithm.to_string(),
))?
.to_lowercase();

name.parse::<HashAlgorithm>()
.map_err(|_| Error::InvalidHashAlgorithm(name))?
}
None => DEFAULT_HASH_ALGORITHM,
};

Ok(algorithm)
}

async fn build_request(tee: Tee) -> Request {
let extra_params = get_request_extra_params().await;

Expand Down Expand Up @@ -168,19 +188,7 @@ impl KbsClient<Box<dyn EvidenceProvider>> {

let extra_params = challenge.extra_params;

let algorithm = match extra_params.get(SELECTED_HASH_ALGORITHM_JSON_KEY) {
Some(selected_hash_algorithm) => {
// Note the blank string which will be handled as an error when parsed.
let name = selected_hash_algorithm
.as_str()
.unwrap_or("")
.to_lowercase();

name.parse::<HashAlgorithm>()
.map_err(|_| Error::InvalidHashAlgorithm(name))?
}
None => DEFAULT_HASH_ALGORITHM,
};
let algorithm = get_hash_algorithm(extra_params)?;

let tee_pubkey = self.tee_key.export_pubkey()?;
let runtime_data = json!({
Expand Down Expand Up @@ -350,16 +358,19 @@ impl KbsClientCapabilities for KbsClient<Box<dyn EvidenceProvider>> {
#[cfg(test)]
mod test {
use crypto::HashAlgorithm;
use rstest::rstest;
use serde_json::{json, Value};
use std::{env, path::PathBuf, time::Duration};
use testcontainers::{clients, images::generic::GenericImage};
use tokio::fs;

use crate::{
evidence_provider::NativeEvidenceProvider, KbsClientBuilder, KbsClientCapabilities,
evidence_provider::NativeEvidenceProvider, Error, KbsClientBuilder, KbsClientCapabilities,
};

use crate::client::rcar_client::{
build_request, get_request_extra_params, KBS_PROTOCOL_VERSION,
build_request, get_hash_algorithm, get_request_extra_params, Result,
DEFAULT_HASH_ALGORITHM, KBS_PROTOCOL_VERSION, SELECTED_HASH_ALGORITHM_JSON_KEY,
SUPPORTED_HASH_ALGORITHMS_JSON_KEY,
};
use kbs_types::Tee;
Expand Down Expand Up @@ -502,4 +513,49 @@ mod test {
assert_eq!(request.extra_params, expected_extra_params);
}
}

#[rstest]
#[case(json!({}), Ok(DEFAULT_HASH_ALGORITHM))]
#[case(json!({SELECTED_HASH_ALGORITHM_JSON_KEY: ""}), Err(Error::InvalidHashAlgorithm("".into())))]
#[case(json!({SELECTED_HASH_ALGORITHM_JSON_KEY: "foo"}), Err(Error::InvalidHashAlgorithm("foo".into())))]
#[case(json!({SELECTED_HASH_ALGORITHM_JSON_KEY: "sha256"}), Ok(HashAlgorithm::Sha256))]
#[case(json!({SELECTED_HASH_ALGORITHM_JSON_KEY: "SHA256"}), Ok(HashAlgorithm::Sha256))]
#[case(json!({SELECTED_HASH_ALGORITHM_JSON_KEY: "sha384"}), Ok(HashAlgorithm::Sha384))]
#[case(json!({SELECTED_HASH_ALGORITHM_JSON_KEY: "SHA384"}), Ok(HashAlgorithm::Sha384))]
#[case(json!({SELECTED_HASH_ALGORITHM_JSON_KEY: "sha512"}), Ok(HashAlgorithm::Sha512))]
#[case(json!({SELECTED_HASH_ALGORITHM_JSON_KEY: "SHA512"}), Ok(HashAlgorithm::Sha512))]
#[case(json!({SELECTED_HASH_ALGORITHM_JSON_KEY: []}), Err(Error::UnexpectedJSONDataType("string".into(), "[]".into())))]
#[case(json!({SELECTED_HASH_ALGORITHM_JSON_KEY: {}}), Err(Error::UnexpectedJSONDataType("string".into(), "{}".into())))]
#[case(json!({SELECTED_HASH_ALGORITHM_JSON_KEY: true}), Err(Error::UnexpectedJSONDataType("string".into(), "true".into())))]
#[case(json!({SELECTED_HASH_ALGORITHM_JSON_KEY: 99999}), Err(Error::UnexpectedJSONDataType("string".into(), "99999".into())))]
#[case(json!({SELECTED_HASH_ALGORITHM_JSON_KEY: 3.141}), Err(Error::UnexpectedJSONDataType("string".into(), "3.141".into())))]
fn test_get_hash_algorithm(
#[case] extra_params: Value,
#[case] expected_result: Result<HashAlgorithm>,
) {
let msg =
format!("test: extra_params: {extra_params:?}, expected result: {expected_result:?}");

let actual_result = get_hash_algorithm(extra_params);

let msg = format!("{msg}, actual result: {actual_result:?}");

if std::env::var("DEBUG").is_ok() {
println!("DEBUG: {}", msg);
}

if expected_result.is_err() {
let expected_result_msg = format!("{expected_result:?}");
let actual_result_msg = format!("{actual_result:?}");

assert_eq!(expected_result_msg, actual_result_msg, "{msg:?}");

return;
}

let expected_hash_algorithm = expected_result.unwrap();
let actual_hash_algorithm = actual_result.unwrap();

assert_eq!(expected_hash_algorithm, actual_hash_algorithm, "{msg:?}");
}
}
3 changes: 3 additions & 0 deletions attestation-agent/kbs_protocol/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,7 @@ pub enum Error {

#[error("invalid hash algorithm: {0}")]
InvalidHashAlgorithm(String),

#[error("unexpected JSON data type: expected {0}, got {1}")]
UnexpectedJSONDataType(String, String),
}
Loading