From c42dea0367b2767d8d2a220e4d4a42e901626846 Mon Sep 17 00:00:00 2001 From: Mikko Ylinen Date: Tue, 30 Jul 2024 18:58:49 +0300 Subject: [PATCH] kbs: add ProtocolVersion error kbs already supports checking the Request version but any version mismatch is not correctly returned to the client (nor checked by the current RCAR client handshake). Add an explicit kbs ProtocolVersion error that is returned when the Request version is higher than what the KBS claims to support. Signed-off-by: Mikko Ylinen --- kbs/src/http/attest.rs | 27 +++++++++++++++++++++++++++ kbs/src/http/error.rs | 4 ++++ kbs/src/lib.rs | 22 ++-------------------- kbs/src/session.rs | 7 +------ 4 files changed, 34 insertions(+), 26 deletions(-) diff --git a/kbs/src/http/attest.rs b/kbs/src/http/attest.rs index c8dd2426e..5089fc00d 100644 --- a/kbs/src/http/attest.rs +++ b/kbs/src/http/attest.rs @@ -11,8 +11,27 @@ use base64::engine::general_purpose::{STANDARD, URL_SAFE_NO_PAD}; use base64::Engine; use kbs_types::Challenge; use log::{debug, error, info}; +use semver::{BuildMetadata, Prerelease, Version, VersionReq}; use serde_json::json; +static KBS_MAJOR_VERSION: u64 = 0; +static KBS_MINOR_VERSION: u64 = 1; +static KBS_PATCH_VERSION: u64 = 0; + +lazy_static! { + static ref VERSION_REQ: VersionReq = { + let kbs_version = Version { + major: KBS_MAJOR_VERSION, + minor: KBS_MINOR_VERSION, + patch: KBS_PATCH_VERSION, + pre: Prerelease::EMPTY, + build: BuildMetadata::EMPTY, + }; + + VersionReq::parse(&format!("<={kbs_version}")).unwrap() + }; +} + /// POST /auth pub(crate) async fn auth( request: web::Json, @@ -22,6 +41,14 @@ pub(crate) async fn auth( ) -> Result { info!("Auth API called."); debug!("Auth Request: {:?}", &request); + let version = Version::parse(&request.version).unwrap(); + if !VERSION_REQ.matches(&version) { + raise_error!(Error::ProtocolVersion(format!( + "expected version: {}, requested version: {}", + *VERSION_REQ, + request.version.clone() + ))); + } let challenge = attestation_service .generate_challenge(request.tee, request.extra_params.clone()) diff --git a/kbs/src/http/error.rs b/kbs/src/http/error.rs index 147cc3e33..d278e2d8f 100644 --- a/kbs/src/http/error.rs +++ b/kbs/src/http/error.rs @@ -58,6 +58,9 @@ pub enum Error { #[error("Resource not permitted.")] PolicyReject, + #[error("KBS Client Protocol Version Mismatch: {0}")] + ProtocolVersion(String), + #[error("Public key get failed: {0}")] PublicKeyGetFailed(String), @@ -140,6 +143,7 @@ mod tests { #[case(Error::JWEFailed("test".into()))] #[case(Error::PolicyEndpoint("test".into()))] #[case(Error::PolicyReject)] + #[case(Error::ProtocolVersion("test".into()))] #[case(Error::PublicKeyGetFailed("test".into()))] #[case(Error::ReadSecretFailed("test".into()))] #[case(Error::SetSecretFailed("test".into()))] diff --git a/kbs/src/lib.rs b/kbs/src/lib.rs index 1eb7523e8..5d5177598 100644 --- a/kbs/src/lib.rs +++ b/kbs/src/lib.rs @@ -24,7 +24,6 @@ use attestation::AttestationService; use jwt_simple::prelude::Ed25519PublicKey; #[cfg(feature = "resource")] use resource::RepositoryConfig; -use semver::{BuildMetadata, Prerelease, Version, VersionReq}; #[cfg(feature = "as")] use std::sync::Arc; use std::{net::SocketAddr, path::PathBuf}; @@ -68,28 +67,11 @@ mod token; /// Resource Policy Engine pub mod policy_engine; -static KBS_PREFIX: &str = "/kbs"; -static KBS_MAJOR_VERSION: u64 = 0; -static KBS_MINOR_VERSION: u64 = 1; -static KBS_PATCH_VERSION: u64 = 0; - -lazy_static! { - static ref VERSION_REQ: VersionReq = { - let kbs_version = Version { - major: KBS_MAJOR_VERSION, - minor: KBS_MINOR_VERSION, - patch: KBS_PATCH_VERSION, - pre: Prerelease::EMPTY, - build: BuildMetadata::EMPTY, - }; - - VersionReq::parse(&format!("<={kbs_version}")).unwrap() - }; -} +static KBS_PREFIX: &str = "/kbs/v0"; macro_rules! kbs_path { ($path:expr) => { - format!("{}/v{}/{}", KBS_PREFIX, KBS_MAJOR_VERSION, $path) + format!("{}/{}", KBS_PREFIX, $path) }; } diff --git a/kbs/src/session.rs b/kbs/src/session.rs index 6c075defd..ec2169d3b 100644 --- a/kbs/src/session.rs +++ b/kbs/src/session.rs @@ -6,10 +6,9 @@ use actix_web::cookie::{ time::{Duration, OffsetDateTime}, Cookie, }; -use anyhow::{bail, Result}; +use anyhow::Result; use kbs_types::{Challenge, Request}; use log::warn; -use semver::Version; use uuid::Uuid; pub(crate) static KBS_SESSION_ID: &str = "kbs-session-id"; @@ -52,10 +51,6 @@ macro_rules! impl_member { impl SessionStatus { pub fn auth(request: Request, timeout: i64, challenge: Challenge) -> Result { - let version = Version::parse(&request.version).map_err(anyhow::Error::from)?; - if !crate::VERSION_REQ.matches(&version) { - bail!("Invalid Request version {}", request.version); - } let id = Uuid::new_v4().as_simple().to_string(); let timeout = OffsetDateTime::now_utc() + Duration::minutes(timeout);