diff --git a/Cargo.lock b/Cargo.lock index b399baad8..b3c71ed94 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2909,6 +2909,7 @@ dependencies = [ "openssl", "p12", "prost 0.11.9", + "protobuf 3.3.0", "rand 0.8.5", "reqwest", "resource_uri", @@ -2923,6 +2924,8 @@ dependencies = [ "toml 0.8.8", "tonic", "tonic-build", + "ttrpc", + "ttrpc-codegen", "url", "uuid", "yasna 0.5.2", diff --git a/confidential-data-hub/Makefile b/confidential-data-hub/Makefile index 0d7857d35..10d959582 100644 --- a/confidential-data-hub/Makefile +++ b/confidential-data-hub/Makefile @@ -100,5 +100,5 @@ clean: help: @echo "==========================Help=========================================" - @echo "build: make [DEBUG=1] [LIBC=(musl)] [ARCH=(x86_64/s390x/ppc64le)] [RESOURCE_PROVIDER=(kbs/sev)] [KMS_PROVIDER=aliyun/ehsm]" + @echo "build: make [DEBUG=1] [LIBC=(musl)] [ARCH=(x86_64/s390x/ppc64le)] [RESOURCE_PROVIDER=(kbs/resource_kbs/sev)] [KMS_PROVIDER=aliyun/ehsm]" @echo "install: make install [DESTDIR=/path/to/target] [LIBC=(musl)]" diff --git a/confidential-data-hub/hub/Cargo.toml b/confidential-data-hub/hub/Cargo.toml index 0f648ec66..9fe9597ec 100644 --- a/confidential-data-hub/hub/Cargo.toml +++ b/confidential-data-hub/hub/Cargo.toml @@ -40,9 +40,12 @@ default = ["kbs"] # support aliyun stacks (KMS, ..) aliyun = ["image/aliyun", "secret/aliyun"] -# support coco-KBS to provide confidential resources +# support coco-KBS in Background Check Mode to provide confidential resources kbs = ["image/kbs", "kms/kbs", "secret/kbs"] +# support coco-KBS and coco-AS in Passport Mode to provide confidential resources +resource_kbs = ["image/resource_kbs", "kms/resource_kbs", "secret/resource_kbs"] + # support sev to provide confidential resources sev = ["attestation_agent", "image/sev", "kms/sev", "dep:sev", "secret/sev"] diff --git a/confidential-data-hub/hub/src/hub.rs b/confidential-data-hub/hub/src/hub.rs index f9fb6fe83..d88db6101 100644 --- a/confidential-data-hub/hub/src/hub.rs +++ b/confidential-data-hub/hub/src/hub.rs @@ -67,9 +67,21 @@ impl DataHub for Hub { async fn get_resource(&self, uri: String) -> Result> { info!("get resource called: {uri}"); // to initialize a get_resource_provider client we do not need the ProviderSettings. + #[cfg(feature = "kbs")] let mut client = kms::new_getter("kbs", ProviderSettings::default()) .await - .map_err(|e| Error::GetResource(format!("create kbs client failed: {e}")))?; + .map_err(|e| { + Error::GetResource(format!( + "create kbs client (background check mode) failed: {e}" + )) + })?; + + #[cfg(feature = "resource_kbs")] + let mut client = kms::new_getter("resource_kbs", ProviderSettings::default()) + .await + .map_err(|e| { + Error::GetResource(format!("create kbs client (passport mode) failed: {e}")) + })?; // to get resource using a get_resource_provider client we do not need the Annotations. let res = client diff --git a/confidential-data-hub/image/Cargo.toml b/confidential-data-hub/image/Cargo.toml index 1760b86c5..006d095fc 100644 --- a/confidential-data-hub/image/Cargo.toml +++ b/confidential-data-hub/image/Cargo.toml @@ -24,6 +24,7 @@ default = [] # legacy AnnotationPacket format, s.t. legacy encrypted image format relies on `kbs` feature kbs = ["kms/kbs"] +resource_kbs = ["kms/resource_kbs"] aliyun = ["kms/aliyun"] sev = ["kms/sev"] ehsm = ["kms/ehsm"] diff --git a/confidential-data-hub/kms/Cargo.toml b/confidential-data-hub/kms/Cargo.toml index 46e386414..76f7ebca0 100644 --- a/confidential-data-hub/kms/Cargo.toml +++ b/confidential-data-hub/kms/Cargo.toml @@ -22,6 +22,7 @@ log.workspace = true openssl = { workspace = true, optional = true } p12 = { version = "0.6.3", optional = true } prost = { workspace = true, optional = true } +protobuf.workspace = true rand = { workspace = true, optional = true } reqwest = { workspace = true, optional = true } resource_uri = { path = "../../attestation-agent/deps/resource_uri" } @@ -34,6 +35,7 @@ thiserror.workspace = true tokio = { workspace = true, features = ["fs"] } toml.workspace = true tonic = { workspace = true, optional = true } +ttrpc.workspace = true url = { workspace = true, optional = true } uuid = { workspace = true, features = ["serde", "v4"], optional = true } yasna = { version = "0.5.2", optional = true } @@ -46,11 +48,13 @@ tokio = { workspace = true, features = ["rt", "macros" ] } [build-dependencies] anyhow.workspace = true tonic-build.workspace = true +ttrpc-codegen.workspace = true [features] -default = ["aliyun", "kbs", "ehsm"] +default = ["aliyun", "resource_kbs", "ehsm"] aliyun = ["chrono", "hex", "openssl", "p12", "prost", "rand", "reqwest/rustls-tls", "sha2", "tonic", "url", "yasna"] kbs = ["kbs_protocol"] +resource_kbs = ["kbs_protocol"] ehsm = ["ehsm_client"] sev = ["bincode", "crypto", "dep:sev", "prost", "tonic", "uuid", "zeroize"] diff --git a/confidential-data-hub/kms/build.rs b/confidential-data-hub/kms/build.rs index a8c951230..dff7873fa 100644 --- a/confidential-data-hub/kms/build.rs +++ b/confidential-data-hub/kms/build.rs @@ -3,6 +3,8 @@ // extern crate tonic_build; use anyhow::*; +use std::fs::File; +use std::io::{Read, Write}; fn main() -> Result<()> { #[cfg(feature = "aliyun")] @@ -16,5 +18,39 @@ fn main() -> Result<()> { .out_dir("./src/plugins/kbs/sev") .compile(&["./src/plugins/kbs/sev/protos/getsecret.proto"], &[""])?; + ttrpc_codegen::Codegen::new() + .out_dir("src/attestation/aa_ttrpc") + .include("../../attestation-agent/protos") + .inputs(["../../attestation-agent/protos/attestation-agent.proto"]) + .rust_protobuf() + .customize(ttrpc_codegen::Customize { + async_all: true, + ..Default::default() + }) + .rust_protobuf_customize(ttrpc_codegen::ProtobufCustomize::default().gen_mod_rs(false)) + .run() + .expect("ttrpc gen async code failed."); + + // Fix clippy warnings of code generated from ttrpc_codegen + replace_text_in_file( + "src/attestation/aa_ttrpc/attestation_agent_ttrpc.rs", + "client: client", + "client", + )?; + + Ok(()) +} + +fn replace_text_in_file(file_name: &str, from: &str, to: &str) -> Result<()> { + let mut src = File::open(file_name)?; + let mut contents = String::new(); + src.read_to_string(&mut contents).unwrap(); + drop(src); + + let new_contents = contents.replace(from, to); + + let mut dst = File::create(file_name)?; + dst.write_all(new_contents.as_bytes())?; + Ok(()) } diff --git a/confidential-data-hub/kms/src/attestation/aa_ttrpc/attestation_agent.rs b/confidential-data-hub/kms/src/attestation/aa_ttrpc/attestation_agent.rs new file mode 100644 index 000000000..77852ccb1 --- /dev/null +++ b/confidential-data-hub/kms/src/attestation/aa_ttrpc/attestation_agent.rs @@ -0,0 +1,1182 @@ +// This file is generated by rust-protobuf 3.3.0. Do not edit +// .proto file is parsed by pure +// @generated + +// https://github.com/rust-lang/rust-clippy/issues/702 +#![allow(unknown_lints)] +#![allow(clippy::all)] + +#![allow(unused_attributes)] +#![cfg_attr(rustfmt, rustfmt::skip)] + +#![allow(box_pointers)] +#![allow(dead_code)] +#![allow(missing_docs)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(trivial_casts)] +#![allow(unused_results)] +#![allow(unused_mut)] + +//! Generated file from `attestation-agent.proto` + +/// Generated files are compatible only with the same version +/// of protobuf runtime. +const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_3_3_0; + +// @@protoc_insertion_point(message:attestation_agent.GetEvidenceRequest) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct GetEvidenceRequest { + // message fields + // @@protoc_insertion_point(field:attestation_agent.GetEvidenceRequest.RuntimeData) + pub RuntimeData: ::std::vec::Vec, + // special fields + // @@protoc_insertion_point(special_field:attestation_agent.GetEvidenceRequest.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a GetEvidenceRequest { + fn default() -> &'a GetEvidenceRequest { + ::default_instance() + } +} + +impl GetEvidenceRequest { + pub fn new() -> GetEvidenceRequest { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(1); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "RuntimeData", + |m: &GetEvidenceRequest| { &m.RuntimeData }, + |m: &mut GetEvidenceRequest| { &mut m.RuntimeData }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "GetEvidenceRequest", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for GetEvidenceRequest { + const NAME: &'static str = "GetEvidenceRequest"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + self.RuntimeData = is.read_bytes()?; + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if !self.RuntimeData.is_empty() { + my_size += ::protobuf::rt::bytes_size(1, &self.RuntimeData); + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if !self.RuntimeData.is_empty() { + os.write_bytes(1, &self.RuntimeData)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> GetEvidenceRequest { + GetEvidenceRequest::new() + } + + fn clear(&mut self) { + self.RuntimeData.clear(); + self.special_fields.clear(); + } + + fn default_instance() -> &'static GetEvidenceRequest { + static instance: GetEvidenceRequest = GetEvidenceRequest { + RuntimeData: ::std::vec::Vec::new(), + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for GetEvidenceRequest { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("GetEvidenceRequest").unwrap()).clone() + } +} + +impl ::std::fmt::Display for GetEvidenceRequest { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for GetEvidenceRequest { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; +} + +// @@protoc_insertion_point(message:attestation_agent.GetEvidenceResponse) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct GetEvidenceResponse { + // message fields + // @@protoc_insertion_point(field:attestation_agent.GetEvidenceResponse.Evidence) + pub Evidence: ::std::vec::Vec, + // special fields + // @@protoc_insertion_point(special_field:attestation_agent.GetEvidenceResponse.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a GetEvidenceResponse { + fn default() -> &'a GetEvidenceResponse { + ::default_instance() + } +} + +impl GetEvidenceResponse { + pub fn new() -> GetEvidenceResponse { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(1); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "Evidence", + |m: &GetEvidenceResponse| { &m.Evidence }, + |m: &mut GetEvidenceResponse| { &mut m.Evidence }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "GetEvidenceResponse", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for GetEvidenceResponse { + const NAME: &'static str = "GetEvidenceResponse"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + self.Evidence = is.read_bytes()?; + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if !self.Evidence.is_empty() { + my_size += ::protobuf::rt::bytes_size(1, &self.Evidence); + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if !self.Evidence.is_empty() { + os.write_bytes(1, &self.Evidence)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> GetEvidenceResponse { + GetEvidenceResponse::new() + } + + fn clear(&mut self) { + self.Evidence.clear(); + self.special_fields.clear(); + } + + fn default_instance() -> &'static GetEvidenceResponse { + static instance: GetEvidenceResponse = GetEvidenceResponse { + Evidence: ::std::vec::Vec::new(), + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for GetEvidenceResponse { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("GetEvidenceResponse").unwrap()).clone() + } +} + +impl ::std::fmt::Display for GetEvidenceResponse { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for GetEvidenceResponse { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; +} + +// @@protoc_insertion_point(message:attestation_agent.GetTokenRequest) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct GetTokenRequest { + // message fields + // @@protoc_insertion_point(field:attestation_agent.GetTokenRequest.TokenType) + pub TokenType: ::std::string::String, + // special fields + // @@protoc_insertion_point(special_field:attestation_agent.GetTokenRequest.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a GetTokenRequest { + fn default() -> &'a GetTokenRequest { + ::default_instance() + } +} + +impl GetTokenRequest { + pub fn new() -> GetTokenRequest { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(1); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "TokenType", + |m: &GetTokenRequest| { &m.TokenType }, + |m: &mut GetTokenRequest| { &mut m.TokenType }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "GetTokenRequest", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for GetTokenRequest { + const NAME: &'static str = "GetTokenRequest"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + self.TokenType = is.read_string()?; + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if !self.TokenType.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.TokenType); + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if !self.TokenType.is_empty() { + os.write_string(1, &self.TokenType)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> GetTokenRequest { + GetTokenRequest::new() + } + + fn clear(&mut self) { + self.TokenType.clear(); + self.special_fields.clear(); + } + + fn default_instance() -> &'static GetTokenRequest { + static instance: GetTokenRequest = GetTokenRequest { + TokenType: ::std::string::String::new(), + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for GetTokenRequest { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("GetTokenRequest").unwrap()).clone() + } +} + +impl ::std::fmt::Display for GetTokenRequest { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for GetTokenRequest { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; +} + +// @@protoc_insertion_point(message:attestation_agent.GetTokenResponse) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct GetTokenResponse { + // message fields + // @@protoc_insertion_point(field:attestation_agent.GetTokenResponse.Token) + pub Token: ::std::vec::Vec, + // special fields + // @@protoc_insertion_point(special_field:attestation_agent.GetTokenResponse.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a GetTokenResponse { + fn default() -> &'a GetTokenResponse { + ::default_instance() + } +} + +impl GetTokenResponse { + pub fn new() -> GetTokenResponse { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(1); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "Token", + |m: &GetTokenResponse| { &m.Token }, + |m: &mut GetTokenResponse| { &mut m.Token }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "GetTokenResponse", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for GetTokenResponse { + const NAME: &'static str = "GetTokenResponse"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + self.Token = is.read_bytes()?; + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if !self.Token.is_empty() { + my_size += ::protobuf::rt::bytes_size(1, &self.Token); + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if !self.Token.is_empty() { + os.write_bytes(1, &self.Token)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> GetTokenResponse { + GetTokenResponse::new() + } + + fn clear(&mut self) { + self.Token.clear(); + self.special_fields.clear(); + } + + fn default_instance() -> &'static GetTokenResponse { + static instance: GetTokenResponse = GetTokenResponse { + Token: ::std::vec::Vec::new(), + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for GetTokenResponse { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("GetTokenResponse").unwrap()).clone() + } +} + +impl ::std::fmt::Display for GetTokenResponse { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for GetTokenResponse { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; +} + +// @@protoc_insertion_point(message:attestation_agent.ExtendRuntimeMeasurementRequest) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct ExtendRuntimeMeasurementRequest { + // message fields + // @@protoc_insertion_point(field:attestation_agent.ExtendRuntimeMeasurementRequest.Events) + pub Events: ::std::vec::Vec<::std::vec::Vec>, + // @@protoc_insertion_point(field:attestation_agent.ExtendRuntimeMeasurementRequest.RegisterIndex) + pub RegisterIndex: ::std::option::Option, + // special fields + // @@protoc_insertion_point(special_field:attestation_agent.ExtendRuntimeMeasurementRequest.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a ExtendRuntimeMeasurementRequest { + fn default() -> &'a ExtendRuntimeMeasurementRequest { + ::default_instance() + } +} + +impl ExtendRuntimeMeasurementRequest { + pub fn new() -> ExtendRuntimeMeasurementRequest { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(2); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_vec_simpler_accessor::<_, _>( + "Events", + |m: &ExtendRuntimeMeasurementRequest| { &m.Events }, + |m: &mut ExtendRuntimeMeasurementRequest| { &mut m.Events }, + )); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "RegisterIndex", + |m: &ExtendRuntimeMeasurementRequest| { &m.RegisterIndex }, + |m: &mut ExtendRuntimeMeasurementRequest| { &mut m.RegisterIndex }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "ExtendRuntimeMeasurementRequest", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for ExtendRuntimeMeasurementRequest { + const NAME: &'static str = "ExtendRuntimeMeasurementRequest"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + self.Events.push(is.read_bytes()?); + }, + 16 => { + self.RegisterIndex = ::std::option::Option::Some(is.read_uint64()?); + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + for value in &self.Events { + my_size += ::protobuf::rt::bytes_size(1, &value); + }; + if let Some(v) = self.RegisterIndex { + my_size += ::protobuf::rt::uint64_size(2, v); + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + for v in &self.Events { + os.write_bytes(1, &v)?; + }; + if let Some(v) = self.RegisterIndex { + os.write_uint64(2, v)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> ExtendRuntimeMeasurementRequest { + ExtendRuntimeMeasurementRequest::new() + } + + fn clear(&mut self) { + self.Events.clear(); + self.RegisterIndex = ::std::option::Option::None; + self.special_fields.clear(); + } + + fn default_instance() -> &'static ExtendRuntimeMeasurementRequest { + static instance: ExtendRuntimeMeasurementRequest = ExtendRuntimeMeasurementRequest { + Events: ::std::vec::Vec::new(), + RegisterIndex: ::std::option::Option::None, + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for ExtendRuntimeMeasurementRequest { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("ExtendRuntimeMeasurementRequest").unwrap()).clone() + } +} + +impl ::std::fmt::Display for ExtendRuntimeMeasurementRequest { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for ExtendRuntimeMeasurementRequest { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; +} + +// @@protoc_insertion_point(message:attestation_agent.ExtendRuntimeMeasurementResponse) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct ExtendRuntimeMeasurementResponse { + // special fields + // @@protoc_insertion_point(special_field:attestation_agent.ExtendRuntimeMeasurementResponse.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a ExtendRuntimeMeasurementResponse { + fn default() -> &'a ExtendRuntimeMeasurementResponse { + ::default_instance() + } +} + +impl ExtendRuntimeMeasurementResponse { + pub fn new() -> ExtendRuntimeMeasurementResponse { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(0); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "ExtendRuntimeMeasurementResponse", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for ExtendRuntimeMeasurementResponse { + const NAME: &'static str = "ExtendRuntimeMeasurementResponse"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> ExtendRuntimeMeasurementResponse { + ExtendRuntimeMeasurementResponse::new() + } + + fn clear(&mut self) { + self.special_fields.clear(); + } + + fn default_instance() -> &'static ExtendRuntimeMeasurementResponse { + static instance: ExtendRuntimeMeasurementResponse = ExtendRuntimeMeasurementResponse { + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for ExtendRuntimeMeasurementResponse { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("ExtendRuntimeMeasurementResponse").unwrap()).clone() + } +} + +impl ::std::fmt::Display for ExtendRuntimeMeasurementResponse { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for ExtendRuntimeMeasurementResponse { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; +} + +// @@protoc_insertion_point(message:attestation_agent.InitDataPlaintext) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct InitDataPlaintext { + // message fields + // @@protoc_insertion_point(field:attestation_agent.InitDataPlaintext.Content) + pub Content: ::std::vec::Vec, + // @@protoc_insertion_point(field:attestation_agent.InitDataPlaintext.Algorithm) + pub Algorithm: ::std::string::String, + // special fields + // @@protoc_insertion_point(special_field:attestation_agent.InitDataPlaintext.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a InitDataPlaintext { + fn default() -> &'a InitDataPlaintext { + ::default_instance() + } +} + +impl InitDataPlaintext { + pub fn new() -> InitDataPlaintext { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(2); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "Content", + |m: &InitDataPlaintext| { &m.Content }, + |m: &mut InitDataPlaintext| { &mut m.Content }, + )); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "Algorithm", + |m: &InitDataPlaintext| { &m.Algorithm }, + |m: &mut InitDataPlaintext| { &mut m.Algorithm }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "InitDataPlaintext", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for InitDataPlaintext { + const NAME: &'static str = "InitDataPlaintext"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + self.Content = is.read_bytes()?; + }, + 18 => { + self.Algorithm = is.read_string()?; + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if !self.Content.is_empty() { + my_size += ::protobuf::rt::bytes_size(1, &self.Content); + } + if !self.Algorithm.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.Algorithm); + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if !self.Content.is_empty() { + os.write_bytes(1, &self.Content)?; + } + if !self.Algorithm.is_empty() { + os.write_string(2, &self.Algorithm)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> InitDataPlaintext { + InitDataPlaintext::new() + } + + fn clear(&mut self) { + self.Content.clear(); + self.Algorithm.clear(); + self.special_fields.clear(); + } + + fn default_instance() -> &'static InitDataPlaintext { + static instance: InitDataPlaintext = InitDataPlaintext { + Content: ::std::vec::Vec::new(), + Algorithm: ::std::string::String::new(), + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for InitDataPlaintext { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("InitDataPlaintext").unwrap()).clone() + } +} + +impl ::std::fmt::Display for InitDataPlaintext { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for InitDataPlaintext { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; +} + +// @@protoc_insertion_point(message:attestation_agent.CheckInitDataRequest) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct CheckInitDataRequest { + // message fields + // @@protoc_insertion_point(field:attestation_agent.CheckInitDataRequest.Digest) + pub Digest: ::std::vec::Vec, + // special fields + // @@protoc_insertion_point(special_field:attestation_agent.CheckInitDataRequest.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a CheckInitDataRequest { + fn default() -> &'a CheckInitDataRequest { + ::default_instance() + } +} + +impl CheckInitDataRequest { + pub fn new() -> CheckInitDataRequest { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(1); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "Digest", + |m: &CheckInitDataRequest| { &m.Digest }, + |m: &mut CheckInitDataRequest| { &mut m.Digest }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "CheckInitDataRequest", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for CheckInitDataRequest { + const NAME: &'static str = "CheckInitDataRequest"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + self.Digest = is.read_bytes()?; + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if !self.Digest.is_empty() { + my_size += ::protobuf::rt::bytes_size(1, &self.Digest); + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if !self.Digest.is_empty() { + os.write_bytes(1, &self.Digest)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> CheckInitDataRequest { + CheckInitDataRequest::new() + } + + fn clear(&mut self) { + self.Digest.clear(); + self.special_fields.clear(); + } + + fn default_instance() -> &'static CheckInitDataRequest { + static instance: CheckInitDataRequest = CheckInitDataRequest { + Digest: ::std::vec::Vec::new(), + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for CheckInitDataRequest { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("CheckInitDataRequest").unwrap()).clone() + } +} + +impl ::std::fmt::Display for CheckInitDataRequest { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for CheckInitDataRequest { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; +} + +// @@protoc_insertion_point(message:attestation_agent.CheckInitDataResponse) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct CheckInitDataResponse { + // special fields + // @@protoc_insertion_point(special_field:attestation_agent.CheckInitDataResponse.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a CheckInitDataResponse { + fn default() -> &'a CheckInitDataResponse { + ::default_instance() + } +} + +impl CheckInitDataResponse { + pub fn new() -> CheckInitDataResponse { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(0); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "CheckInitDataResponse", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for CheckInitDataResponse { + const NAME: &'static str = "CheckInitDataResponse"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> CheckInitDataResponse { + CheckInitDataResponse::new() + } + + fn clear(&mut self) { + self.special_fields.clear(); + } + + fn default_instance() -> &'static CheckInitDataResponse { + static instance: CheckInitDataResponse = CheckInitDataResponse { + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for CheckInitDataResponse { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("CheckInitDataResponse").unwrap()).clone() + } +} + +impl ::std::fmt::Display for CheckInitDataResponse { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for CheckInitDataResponse { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; +} + +static file_descriptor_proto_data: &'static [u8] = b"\ + \n\x17attestation-agent.proto\x12\x11attestation_agent\"6\n\x12GetEviden\ + ceRequest\x12\x20\n\x0bRuntimeData\x18\x01\x20\x01(\x0cR\x0bRuntimeData\ + \"1\n\x13GetEvidenceResponse\x12\x1a\n\x08Evidence\x18\x01\x20\x01(\x0cR\ + \x08Evidence\"/\n\x0fGetTokenRequest\x12\x1c\n\tTokenType\x18\x01\x20\ + \x01(\tR\tTokenType\"(\n\x10GetTokenResponse\x12\x14\n\x05Token\x18\x01\ + \x20\x01(\x0cR\x05Token\"v\n\x1fExtendRuntimeMeasurementRequest\x12\x16\ + \n\x06Events\x18\x01\x20\x03(\x0cR\x06Events\x12)\n\rRegisterIndex\x18\ + \x02\x20\x01(\x04H\0R\rRegisterIndex\x88\x01\x01B\x10\n\x0e_RegisterInde\ + x\"\"\n\x20ExtendRuntimeMeasurementResponse\"K\n\x11InitDataPlaintext\ + \x12\x18\n\x07Content\x18\x01\x20\x01(\x0cR\x07Content\x12\x1c\n\tAlgori\ + thm\x18\x02\x20\x01(\tR\tAlgorithm\".\n\x14CheckInitDataRequest\x12\x16\ + \n\x06Digest\x18\x01\x20\x01(\x0cR\x06Digest\"\x17\n\x15CheckInitDataRes\ + ponse2\xb6\x03\n\x17AttestationAgentService\x12\\\n\x0bGetEvidence\x12%.\ + attestation_agent.GetEvidenceRequest\x1a&.attestation_agent.GetEvidenceR\ + esponse\x12S\n\x08GetToken\x12\".attestation_agent.GetTokenRequest\x1a#.\ + attestation_agent.GetTokenResponse\x12\x83\x01\n\x18ExtendRuntimeMeasure\ + ment\x122.attestation_agent.ExtendRuntimeMeasurementRequest\x1a3.attesta\ + tion_agent.ExtendRuntimeMeasurementResponse\x12b\n\rCheckInitData\x12'.a\ + ttestation_agent.CheckInitDataRequest\x1a(.attestation_agent.CheckInitDa\ + taResponseb\x06proto3\ +"; + +/// `FileDescriptorProto` object which was a source for this generated file +fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { + static file_descriptor_proto_lazy: ::protobuf::rt::Lazy<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::Lazy::new(); + file_descriptor_proto_lazy.get(|| { + ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap() + }) +} + +/// `FileDescriptor` object which allows dynamic access to files +pub fn file_descriptor() -> &'static ::protobuf::reflect::FileDescriptor { + static generated_file_descriptor_lazy: ::protobuf::rt::Lazy<::protobuf::reflect::GeneratedFileDescriptor> = ::protobuf::rt::Lazy::new(); + static file_descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::FileDescriptor> = ::protobuf::rt::Lazy::new(); + file_descriptor.get(|| { + let generated_file_descriptor = generated_file_descriptor_lazy.get(|| { + let mut deps = ::std::vec::Vec::with_capacity(0); + let mut messages = ::std::vec::Vec::with_capacity(9); + messages.push(GetEvidenceRequest::generated_message_descriptor_data()); + messages.push(GetEvidenceResponse::generated_message_descriptor_data()); + messages.push(GetTokenRequest::generated_message_descriptor_data()); + messages.push(GetTokenResponse::generated_message_descriptor_data()); + messages.push(ExtendRuntimeMeasurementRequest::generated_message_descriptor_data()); + messages.push(ExtendRuntimeMeasurementResponse::generated_message_descriptor_data()); + messages.push(InitDataPlaintext::generated_message_descriptor_data()); + messages.push(CheckInitDataRequest::generated_message_descriptor_data()); + messages.push(CheckInitDataResponse::generated_message_descriptor_data()); + let mut enums = ::std::vec::Vec::with_capacity(0); + ::protobuf::reflect::GeneratedFileDescriptor::new_generated( + file_descriptor_proto(), + deps, + messages, + enums, + ) + }); + ::protobuf::reflect::FileDescriptor::new_generated_2(generated_file_descriptor) + }) +} diff --git a/confidential-data-hub/kms/src/attestation/aa_ttrpc/attestation_agent_ttrpc.rs b/confidential-data-hub/kms/src/attestation/aa_ttrpc/attestation_agent_ttrpc.rs new file mode 100644 index 000000000..2f917e3c4 --- /dev/null +++ b/confidential-data-hub/kms/src/attestation/aa_ttrpc/attestation_agent_ttrpc.rs @@ -0,0 +1,135 @@ +// This file is generated by ttrpc-compiler 0.6.2. Do not edit +// @generated + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unknown_lints)] +#![allow(clipto_camel_casepy)] +#![allow(box_pointers)] +#![allow(dead_code)] +#![allow(missing_docs)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(trivial_casts)] +#![allow(unsafe_code)] +#![allow(unused_imports)] +#![allow(unused_results)] +#![allow(clippy::all)] +use protobuf::{CodedInputStream, CodedOutputStream, Message}; +use std::collections::HashMap; +use std::sync::Arc; +use async_trait::async_trait; + +#[derive(Clone)] +pub struct AttestationAgentServiceClient { + client: ::ttrpc::r#async::Client, +} + +impl AttestationAgentServiceClient { + pub fn new(client: ::ttrpc::r#async::Client) -> Self { + AttestationAgentServiceClient { + client, + } + } + + pub async fn get_evidence(&self, ctx: ttrpc::context::Context, req: &super::attestation_agent::GetEvidenceRequest) -> ::ttrpc::Result { + let mut cres = super::attestation_agent::GetEvidenceResponse::new(); + ::ttrpc::async_client_request!(self, ctx, req, "attestation_agent.AttestationAgentService", "GetEvidence", cres); + } + + pub async fn get_token(&self, ctx: ttrpc::context::Context, req: &super::attestation_agent::GetTokenRequest) -> ::ttrpc::Result { + let mut cres = super::attestation_agent::GetTokenResponse::new(); + ::ttrpc::async_client_request!(self, ctx, req, "attestation_agent.AttestationAgentService", "GetToken", cres); + } + + pub async fn extend_runtime_measurement(&self, ctx: ttrpc::context::Context, req: &super::attestation_agent::ExtendRuntimeMeasurementRequest) -> ::ttrpc::Result { + let mut cres = super::attestation_agent::ExtendRuntimeMeasurementResponse::new(); + ::ttrpc::async_client_request!(self, ctx, req, "attestation_agent.AttestationAgentService", "ExtendRuntimeMeasurement", cres); + } + + pub async fn check_init_data(&self, ctx: ttrpc::context::Context, req: &super::attestation_agent::CheckInitDataRequest) -> ::ttrpc::Result { + let mut cres = super::attestation_agent::CheckInitDataResponse::new(); + ::ttrpc::async_client_request!(self, ctx, req, "attestation_agent.AttestationAgentService", "CheckInitData", cres); + } +} + +struct GetEvidenceMethod { + service: Arc>, +} + +#[async_trait] +impl ::ttrpc::r#async::MethodHandler for GetEvidenceMethod { + async fn handler(&self, ctx: ::ttrpc::r#async::TtrpcContext, req: ::ttrpc::Request) -> ::ttrpc::Result<::ttrpc::Response> { + ::ttrpc::async_request_handler!(self, ctx, req, attestation_agent, GetEvidenceRequest, get_evidence); + } +} + +struct GetTokenMethod { + service: Arc>, +} + +#[async_trait] +impl ::ttrpc::r#async::MethodHandler for GetTokenMethod { + async fn handler(&self, ctx: ::ttrpc::r#async::TtrpcContext, req: ::ttrpc::Request) -> ::ttrpc::Result<::ttrpc::Response> { + ::ttrpc::async_request_handler!(self, ctx, req, attestation_agent, GetTokenRequest, get_token); + } +} + +struct ExtendRuntimeMeasurementMethod { + service: Arc>, +} + +#[async_trait] +impl ::ttrpc::r#async::MethodHandler for ExtendRuntimeMeasurementMethod { + async fn handler(&self, ctx: ::ttrpc::r#async::TtrpcContext, req: ::ttrpc::Request) -> ::ttrpc::Result<::ttrpc::Response> { + ::ttrpc::async_request_handler!(self, ctx, req, attestation_agent, ExtendRuntimeMeasurementRequest, extend_runtime_measurement); + } +} + +struct CheckInitDataMethod { + service: Arc>, +} + +#[async_trait] +impl ::ttrpc::r#async::MethodHandler for CheckInitDataMethod { + async fn handler(&self, ctx: ::ttrpc::r#async::TtrpcContext, req: ::ttrpc::Request) -> ::ttrpc::Result<::ttrpc::Response> { + ::ttrpc::async_request_handler!(self, ctx, req, attestation_agent, CheckInitDataRequest, check_init_data); + } +} + +#[async_trait] +pub trait AttestationAgentService: Sync { + async fn get_evidence(&self, _ctx: &::ttrpc::r#async::TtrpcContext, _: super::attestation_agent::GetEvidenceRequest) -> ::ttrpc::Result { + Err(::ttrpc::Error::RpcStatus(::ttrpc::get_status(::ttrpc::Code::NOT_FOUND, "/attestation_agent.AttestationAgentService/GetEvidence is not supported".to_string()))) + } + async fn get_token(&self, _ctx: &::ttrpc::r#async::TtrpcContext, _: super::attestation_agent::GetTokenRequest) -> ::ttrpc::Result { + Err(::ttrpc::Error::RpcStatus(::ttrpc::get_status(::ttrpc::Code::NOT_FOUND, "/attestation_agent.AttestationAgentService/GetToken is not supported".to_string()))) + } + async fn extend_runtime_measurement(&self, _ctx: &::ttrpc::r#async::TtrpcContext, _: super::attestation_agent::ExtendRuntimeMeasurementRequest) -> ::ttrpc::Result { + Err(::ttrpc::Error::RpcStatus(::ttrpc::get_status(::ttrpc::Code::NOT_FOUND, "/attestation_agent.AttestationAgentService/ExtendRuntimeMeasurement is not supported".to_string()))) + } + async fn check_init_data(&self, _ctx: &::ttrpc::r#async::TtrpcContext, _: super::attestation_agent::CheckInitDataRequest) -> ::ttrpc::Result { + Err(::ttrpc::Error::RpcStatus(::ttrpc::get_status(::ttrpc::Code::NOT_FOUND, "/attestation_agent.AttestationAgentService/CheckInitData is not supported".to_string()))) + } +} + +pub fn create_attestation_agent_service(service: Arc>) -> HashMap { + let mut ret = HashMap::new(); + let mut methods = HashMap::new(); + let streams = HashMap::new(); + + methods.insert("GetEvidence".to_string(), + Box::new(GetEvidenceMethod{service: service.clone()}) as Box); + + methods.insert("GetToken".to_string(), + Box::new(GetTokenMethod{service: service.clone()}) as Box); + + methods.insert("ExtendRuntimeMeasurement".to_string(), + Box::new(ExtendRuntimeMeasurementMethod{service: service.clone()}) as Box); + + methods.insert("CheckInitData".to_string(), + Box::new(CheckInitDataMethod{service: service.clone()}) as Box); + + ret.insert("attestation_agent.AttestationAgentService".to_string(), ::ttrpc::r#async::Service{ methods, streams }); + ret +} diff --git a/confidential-data-hub/kms/src/attestation/aa_ttrpc/mod.rs b/confidential-data-hub/kms/src/attestation/aa_ttrpc/mod.rs new file mode 100644 index 000000000..318ec1468 --- /dev/null +++ b/confidential-data-hub/kms/src/attestation/aa_ttrpc/mod.rs @@ -0,0 +1,7 @@ +// Copyright (c) 2024 Alibaba Cloud +// +// SPDX-License-Identifier: Apache-2.0 +// + +pub mod attestation_agent; +pub mod attestation_agent_ttrpc; diff --git a/confidential-data-hub/kms/src/attestation/mod.rs b/confidential-data-hub/kms/src/attestation/mod.rs new file mode 100644 index 000000000..c496aa860 --- /dev/null +++ b/confidential-data-hub/kms/src/attestation/mod.rs @@ -0,0 +1,48 @@ +// Copyright (c) 2024 Alibaba Cloud +// +// SPDX-License-Identifier: Apache-2.0 +// + +mod aa_ttrpc; + +use crate::{Error, Result}; +use ttrpc::context; + +const AA_SOCKET_FILE: &str = + "unix:///run/confidential-containers/attestation-agent/attestation-agent.sock"; + +use aa_ttrpc::{ + attestation_agent::GetTokenRequest, attestation_agent_ttrpc::AttestationAgentServiceClient, +}; + +pub struct AAClient { + client: AttestationAgentServiceClient, +} + +impl AAClient { + pub async fn new() -> Result { + let c = ttrpc::r#async::Client::connect(AA_SOCKET_FILE) + .map_err(|e| Error::AAClientError(format!("ttrpc connect failed {e}")))?; + let client = AttestationAgentServiceClient::new(c); + Ok(Self { client }) + } +} + +impl AAClient { + pub async fn get_token( + &self, + token_type: &str, + structured_runtime_data: &str, + ) -> Result> { + let req = GetTokenRequest { + TokenType: token_type.to_string(), + StructuredRuntimeData: structured_runtime_data.to_string()..Default::default(), + }; + let bytes = self + .client + .get_token(context::with_timeout(50 * 1000 * 1000 * 1000), &req) + .await + .map_err(|e| Error::AAClientError(format!("cal ttrpc failed: {e}")))?; + Ok(bytes.Token) + } +} diff --git a/confidential-data-hub/kms/src/error.rs b/confidential-data-hub/kms/src/error.rs index a0a5247ac..0165072a0 100644 --- a/confidential-data-hub/kms/src/error.rs +++ b/confidential-data-hub/kms/src/error.rs @@ -14,6 +14,13 @@ pub enum Error { #[error("Aliyun KMS error: {0}")] AliyunKmsError(String), + #[error("Attestation Agent client error: {0}")] + AAClientError(String), + + #[cfg(feature = "resource_kbs")] + #[error("Resource KBS client error: {0}")] + ResourceKbsClientError(String), + #[error("Kbs client error: {0}")] KbsClientError(String), diff --git a/confidential-data-hub/kms/src/lib.rs b/confidential-data-hub/kms/src/lib.rs index ca9f7cbd0..6e0fc7718 100644 --- a/confidential-data-hub/kms/src/lib.rs +++ b/confidential-data-hub/kms/src/lib.rs @@ -11,3 +11,5 @@ pub use error::*; pub mod plugins; pub use plugins::{new_decryptor, new_getter}; + +pub mod attestation; diff --git a/confidential-data-hub/kms/src/plugins/mod.rs b/confidential-data-hub/kms/src/plugins/mod.rs index 280f59070..15ac384ae 100644 --- a/confidential-data-hub/kms/src/plugins/mod.rs +++ b/confidential-data-hub/kms/src/plugins/mod.rs @@ -16,6 +16,9 @@ pub mod aliyun; pub mod kbs; +#[cfg(feature = "resource_kbs")] +pub mod resource_kbs; + #[cfg(feature = "ehsm")] pub mod ehsm; @@ -52,9 +55,16 @@ pub async fn new_decryptor( #[derive(AsRefStr, EnumString)] pub enum VaultProvider { + // Background Check Mode KBS (with built-in AS or gRPC AS) + // Including offline_kbc and SEV KBS #[strum(ascii_case_insensitive)] Kbs, + // Passport Mode KBS + #[cfg(feature = "resource_kbs")] + #[strum(serialize = "resource_kbs")] + ResourceKbs, + #[cfg(feature = "aliyun")] #[strum(ascii_case_insensitive)] Aliyun, @@ -70,6 +80,11 @@ pub async fn new_getter( match provider { VaultProvider::Kbs => Ok(Box::new(kbs::KbcClient::new().await?) as Box), + #[cfg(feature = "resource_kbs")] + VaultProvider::ResourceKbs => { + Ok(Box::new(resource_kbs::ResourceKbsClient::default()) as Box) + } + #[cfg(feature = "aliyun")] VaultProvider::Aliyun => Ok(Box::new( aliyun::AliyunKmsClient::from_provider_settings(&_provider_settings).await?, diff --git a/confidential-data-hub/kms/src/plugins/resource_kbs/mod.rs b/confidential-data-hub/kms/src/plugins/resource_kbs/mod.rs new file mode 100644 index 000000000..aba56a63c --- /dev/null +++ b/confidential-data-hub/kms/src/plugins/resource_kbs/mod.rs @@ -0,0 +1,71 @@ +// Copyright (c) 2024 Alibaba Cloud +// +// SPDX-License-Identifier: Apache-2.0 +// + +use crate::{Annotations, Error, Getter, Result}; +use async_trait::async_trait; +use kbs_protocol::KbsClientCapabilities; +use resource_uri::ResourceUri; + +const TOKEN_TYPE: &str = "coco_as"; + +#[derive(Default)] +pub struct ResourceKbsClient; + +#[async_trait] +impl Getter for ResourceKbsClient { + async fn get_secret(&mut self, uri: &str, _annotations: &Annotations) -> Result> { + // Generate TEE key pair + + let tee_key = kbs_protocol::TeeKeyPair::new() + .map_err(|e| Error::ResourceKbsClientError(e.to_string()))?; + let tee_key_pem_str = tee_key + .to_pkcs1_pem() + .map_err(|e| Error::ResourceKbsClientError(e.to_string()))?; + let tee_pubkey = tee_key + .export_pubkey() + .map_err(|e| Error::ResourceKbsClientError(e.to_string()))?; + let tee_pubkey_str = serde_json::to_string(&tee_pubkey) + .map_err(|e| Error::ResourceKbsClientError(e.to_string()))?; + + // Call AA to get Attestation Token and check validation of the token + + let aa_client = crate::attestation::AAClient::new().await?; + let token_bytes = aa_client.get_token(TOKEN_TYPE, &tee_pubkey_str).await?; + let token_str = std::str::from_utf8(&token_bytes) + .map_err(|e| Error::ResourceKbsClientError(e.to_string()))?; + let token = kbs_protocol::Token::new(token_str.to_string()) + .map_err(|e| Error::ResourceKbsClientError(e.to_string()))?; + token + .check_valid() + .map_err(|e| Error::ResourceKbsClientError(e.to_string()))?; + + // Use KBS protocol to request KBS to get resource with Attestation Token + + let resource_uri = ResourceUri::try_from(uri).map_err(|_| { + Error::ResourceKbsClientError(format!("illegal kbs resource uri: {uri}")) + })?; + + let dummy_token_provider = kbs_protocol::token_provider::AATokenProvider::new() + .await + .map_err(|e| { + Error::ResourceKbsClientError(format!("create dummy AA token provider failed: {e}")) + })?; + let kbs_client = kbs_protocol::KbsClientBuilder::with_token_provider( + Box::new(dummy_token_provider), + &resource_uri.kbs_addr, + ) + .set_token(token_str) + .set_tee_key(tee_key_pem_str.as_ref()) + .build() + .map_err(|e| Error::ResourceKbsClientError(format!("create kbs client failed: {e}")))?; + + let secret = kbs_client + .get_resource(resource_uri) + .await + .map_err(|e| Error::ResourceKbsClientError(format!("get resource failed: {e}")))?; + + Ok(secret) + } +} diff --git a/confidential-data-hub/secret/Cargo.toml b/confidential-data-hub/secret/Cargo.toml index 9dcab19ee..9a4eb7e4a 100644 --- a/confidential-data-hub/secret/Cargo.toml +++ b/confidential-data-hub/secret/Cargo.toml @@ -34,5 +34,6 @@ cli = ["clap/derive", "rand", "tokio/rt-multi-thread", "tokio/sync", "tokio/macr aliyun = ["kms/aliyun"] kbs = ["kms/kbs"] +resource_kbs = ["kms/resource_kbs"] sev = ["kms/sev"] ehsm = ["kms/ehsm"]