From 16b7a7c03c8b4087543f7d06047509c310429cad Mon Sep 17 00:00:00 2001 From: Hugues de Valon Date: Wed, 21 Oct 2020 16:05:08 +0100 Subject: [PATCH] Add basic JWT-SVID API support Add wrappers around API method to fetch and validate JWT-SVID. Split X509 and JWT into different directories. Signed-off-by: Hugues de Valon --- spiffe/Cargo.toml | 20 +- spiffe/Makefile | 2 +- spiffe/src/lib.rs | 11 - spiffe/src/svid/jwt.rs | 51 + spiffe/src/svid/mod.rs | 221 +-- spiffe/src/svid/x509.rs | 222 +++ spiffe/src/uri/mod.rs | 21 +- spiffe/src/workload/jwt.rs | 105 ++ spiffe/src/workload/mod.rs | 147 +- spiffe/src/workload/workload_api.proto | 67 +- spiffe/src/workload/workload_api.rs | 1816 +++++++++++++++++++--- spiffe/src/workload/workload_api_grpc.rs | 85 +- spiffe/src/workload/x509.rs | 120 ++ spiffe/tests/svid_test.rs | 4 +- spiffe/tests/workload_test.rs | 49 +- 15 files changed, 2273 insertions(+), 668 deletions(-) create mode 100644 spiffe/src/svid/jwt.rs create mode 100644 spiffe/src/svid/x509.rs create mode 100644 spiffe/src/workload/jwt.rs create mode 100644 spiffe/src/workload/x509.rs diff --git a/spiffe/Cargo.toml b/spiffe/Cargo.toml index fb5939a..302b494 100644 --- a/spiffe/Cargo.toml +++ b/spiffe/Cargo.toml @@ -2,15 +2,19 @@ name = "spiffe" version = "0.1.0" authors = ["Sabree Blackmon "] +edition = "2018" [dependencies] -openssl = { version = "0.10", features = ["vendored"] } -error-chain = "0.12.0" -hyper = "0.10.0" -protobuf = "~2.0" -grpcio = { git = "https://github.com/heavypackets/grpc-rs", version = "0.3", default-features = false, features = ["protobuf-codec"] } -futures = "0.1.24" -lazy_static = "^1.1" +openssl = "0.10.30" +error-chain = "0.12.4" +hyper = "0.13.8" +protobuf = "2.18.0" +grpcio = { git = "https://github.com/tikv/grpc-rs", rev = "b9ddf27a81d5cfef057638ffc2d02bd34d85a422", default-features = false, features = ["protobuf-codec", "openssl"] } +futures = "0.3.6" +lazy_static = "1.4.0" +url = "2.1.1" +log = "0.4.11" +zeroize = { version = "1.1.1", features = ["zeroize_derive"] } [dev-dependencies] -assert_matches = "1.3" +assert_matches = "1.4.0" diff --git a/spiffe/Makefile b/spiffe/Makefile index e208846..78f14dc 100644 --- a/spiffe/Makefile +++ b/spiffe/Makefile @@ -6,7 +6,7 @@ spiffe: cargo build --color always protobuf: - protoc --rust_out=src/api/ --grpc_out=src/api/ --plugin=protoc-gen-grpc=`which grpc_rust_plugin` src/api/workload_api.proto + protoc --rust_out=src/workload/ --grpc_out=src/workload/ --plugin=protoc-gen-grpc=`which grpc_rust_plugin` src/workload/workload_api.proto test: cargo test --color always diff --git a/spiffe/src/lib.rs b/spiffe/src/lib.rs index 53cbb2c..c65d7e4 100644 --- a/spiffe/src/lib.rs +++ b/spiffe/src/lib.rs @@ -1,14 +1,3 @@ -extern crate futures; -extern crate grpcio; -extern crate hyper; -extern crate openssl; -extern crate protobuf; - -#[macro_use] -extern crate error_chain; -#[macro_use] -extern crate lazy_static; - pub mod svid; pub mod uri; pub mod workload; diff --git a/spiffe/src/svid/jwt.rs b/spiffe/src/svid/jwt.rs new file mode 100644 index 0000000..739c376 --- /dev/null +++ b/spiffe/src/svid/jwt.rs @@ -0,0 +1,51 @@ +use crate::svid::{SVIDKind, SVID}; +use crate::uri::URI; +use error_chain::error_chain; +use std::ops::Deref; +use std::str::FromStr; +use zeroize::Zeroize; + +error_chain! { + errors { + InvalidURI { + description("An error occured during the parsing of the SPIFFE ID") + display("The SPIFFE ID can not be parsed into a valid SPIFFE URI") + } + } +} + +impl SVIDKind for Jwt {} + +#[derive(Zeroize)] +#[zeroize(drop)] +pub struct Jwt { + svid: String, +} + +impl Jwt { + pub fn new(svid: String) -> Jwt { + Jwt { svid } + } + + pub fn svid(&self) -> &str { + &self.svid + } +} + +impl SVID { + pub fn new(svid: String, uri: &str) -> Result> { + Ok(SVID:: { + doc: Jwt { svid }, + uri: URI::from_str(uri).chain_err(|| ErrorKind::InvalidURI)?, + }) + } +} + +impl Deref for SVID { + type Target = Jwt; + + fn deref(&self) -> &Jwt { + let SVID:: { doc, .. } = self; + &doc + } +} diff --git a/spiffe/src/svid/mod.rs b/spiffe/src/svid/mod.rs index f9793c1..4fc4a2e 100644 --- a/spiffe/src/svid/mod.rs +++ b/spiffe/src/svid/mod.rs @@ -1,227 +1,12 @@ -use std::fmt; -use std::fs; -use std::ops::Deref; -use std::path::Path; +pub mod jwt; +pub mod x509; -type OpenSSlX509Cert = ::openssl::x509::X509; - -use uri::URI; - -error_chain!{ - errors { - InvalidFilePath(path: String) { - description("An IO error during the parsing of an SVID") - display("Unable to parse SVID: Invalid file path {}", path) - } - - InvalidPEM { - description("An error during the parsing of an SVID PEM") - display("Unable to parse SVID: Not a valid PEM") - } - - InvalidDER { - description("An error during the parsing of an SVID DER") - display("Unable to parse SVID: Not a valid DER") - } - - InvalidSAN { - description("An error during the validation of SVID SANs") - display("Unable to parse SVID: SANs do not contain a valid SPIFFE URI") - } - - MultipleURIFound(first: String, next: String) { - description("An error during the validation of SVID certificate") - display("Multiple valid SPIFFE URIs found in SVID: {} & {}", first, next) - } - } - - links { - Uri(::uri::Error, ::uri::ErrorKind); - } - - foreign_links { - SSL(::openssl::error::ErrorStack); - Io(::std::io::Error); - } -} - -impl<'a> From<&'a Path> for ErrorKind { - fn from(path: &'a Path) -> Self { - ErrorKind::InvalidFilePath(path.to_str().unwrap_or("").to_string()) - } -} +use crate::uri::URI; pub trait SVIDKind {} -pub type Bundle = Vec; -pub type Key = Vec; - -pub struct X509 { - cert: OpenSSlX509Cert, - key: Option, - bundle: Option, -} - -impl X509 { - pub fn new(cert: OpenSSlX509Cert, key: Option, bundle: Option) -> X509 { - X509 { - cert, - key: match key { - Some(k) => Some(k.to_vec()), - None => None, - }, - bundle: match bundle { - Some(b) => Some(b.to_vec()), - None => None, - }, - } - } - - pub fn cert(&self) -> &OpenSSlX509Cert { - &self.cert - } - - pub fn key(&self) -> Option<&Vec> { - match self.key { - Some(ref k) => Some(&k), - None => None, - } - } - - pub fn bundle(&self) -> Option<&Vec> { - match self.bundle { - Some(ref b) => Some(&b), - None => None, - } - } -} - -impl fmt::Debug for X509 { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let X509 { cert, .. } = self; - write!( - f, - "OpenSSL X509 Certificate: {{ {:?} }}", - cert.to_pem().unwrap_or_else(|_| vec![]) - ) - } -} - -impl SVIDKind for X509 {} - #[derive(Debug)] pub struct SVID { doc: T, uri: URI, } - -impl SVID { - pub fn from_pem(pem: &[u8], key: Option, bundle: Option) -> Result> { - let cert = OpenSSlX509Cert::from_pem(pem).chain_err(|| ErrorKind::InvalidPEM)?; - - match SVID::::parse_uri(&cert) { - Ok(uri) => Ok(SVID:: { - doc: X509::new(cert, key, bundle), - uri, - }), - Err(e) => Err(e.chain_err(|| ErrorKind::InvalidSAN)), - } - } - - pub fn from_path(path: &Path, key: Option<&Path>, bundle: Option<&Path>) -> Result> { - let contents = fs::read(path).chain_err(|| path)?; - let cert = - OpenSSlX509Cert::from_pem(contents.as_slice()).chain_err(|| ErrorKind::InvalidPEM)?; - - let key_contents = match key { - Some(path) => Some(fs::read(path).chain_err(|| path)?.to_vec()), - None => None, - }; - let bundle_contents = match bundle { - Some(path) => Some(fs::read(path).chain_err(|| path)?.to_vec()), - None => None, - }; - - match SVID::::parse_uri(&cert) { - Ok(uri) => Ok(SVID:: { - doc: X509::new(cert, key_contents, bundle_contents), - uri, - }), - Err(e) => Err(e.chain_err(|| ErrorKind::InvalidPEM)), - } - } - - pub fn from_der(der: &[u8], key: Option, bundle: Option) -> Result> { - let cert = OpenSSlX509Cert::from_der(der).chain_err(|| ErrorKind::InvalidDER)?; - - match SVID::::parse_uri(&cert) { - Ok(uri) => Ok(SVID:: { - doc: X509::new(cert, key, bundle), - uri, - }), - Err(e) => Err(e.chain_err(|| ErrorKind::InvalidSAN)), - } - } - - pub fn from_x509( - cert: OpenSSlX509Cert, - key: Option, - bundle: Option, - ) -> Result> { - match SVID::::parse_uri(&cert) { - Ok(uri) => Ok(SVID:: { - doc: X509::new(cert, key, bundle), - uri, - }), - Err(e) => Err(e.chain_err(|| ErrorKind::InvalidPEM)), - } - } - - pub fn uri(&self) -> &URI { - let SVID:: { uri, .. } = self; - &uri - } - - pub fn x509(&self) -> &X509 { - let SVID:: { doc, .. } = self; - &doc - } - - pub fn match_spiffe_uri(&self, uri: &str) -> Result { - Ok(self.uri().to_string().eq_ignore_ascii_case(uri)) - } - - fn parse_uri(cert: &OpenSSlX509Cert) -> Result { - let sans = match cert.subject_alt_names() { - Some(val) => val, - None => Err(ErrorKind::InvalidSAN)?, - }; - - let mut validated_uri: Option = None; - // Only allows one valid SPIFFE uri in SAN field per SPIFFE specification - returns error if multiple found - for san_entry in sans { - if let Some(uri) = san_entry.uri() { - if let Ok(spiffe_uri) = uri.parse::() { - if validated_uri.is_some() { - Err(ErrorKind::MultipleURIFound( - validated_uri.unwrap().to_string(), - uri.to_string(), - ))?; - } - validated_uri = Some(spiffe_uri); - } - } - } - - validated_uri.ok_or_else(|| Error::from(ErrorKind::InvalidSAN)) - } -} - -impl Deref for SVID { - type Target = X509; - - fn deref(&self) -> &X509 { - let SVID:: { doc, .. } = self; - &doc - } -} diff --git a/spiffe/src/svid/x509.rs b/spiffe/src/svid/x509.rs new file mode 100644 index 0000000..dfd5bd2 --- /dev/null +++ b/spiffe/src/svid/x509.rs @@ -0,0 +1,222 @@ +use crate::svid::{SVIDKind, SVID}; +use crate::uri; +use crate::uri::URI; +use error_chain::error_chain; +use std::fmt; +use std::fs; +use std::ops::Deref; +use std::path::Path; + +type OpenSSlX509Cert = ::openssl::x509::X509; + +error_chain! { + errors { + InvalidFilePath(path: String) { + description("An IO error during the parsing of an SVID") + display("Unable to parse SVID: Invalid file path {}", path) + } + + InvalidPEM { + description("An error during the parsing of an SVID PEM") + display("Unable to parse SVID: Not a valid PEM") + } + + InvalidDER { + description("An error during the parsing of an SVID DER") + display("Unable to parse SVID: Not a valid DER") + } + + InvalidSAN { + description("An error during the validation of SVID SANs") + display("Unable to parse SVID: SANs do not contain a valid SPIFFE URI") + } + + MultipleURIFound(first: String, next: String) { + description("An error during the validation of SVID certificate") + display("Multiple valid SPIFFE URIs found in SVID: {} & {}", first, next) + } + } + + links { + Uri(uri::Error, uri::ErrorKind); + } + + foreign_links { + SSL(::openssl::error::ErrorStack); + Io(::std::io::Error); + } +} + +impl<'a> From<&'a Path> for ErrorKind { + fn from(path: &'a Path) -> Self { + ErrorKind::InvalidFilePath(path.to_str().unwrap_or("").to_string()) + } +} + +pub type Bundle = Vec; +pub type Key = Vec; + +pub struct X509 { + cert: OpenSSlX509Cert, + key: Option, + bundle: Option, +} + +impl X509 { + pub fn new(cert: OpenSSlX509Cert, key: Option, bundle: Option) -> X509 { + X509 { + cert, + key: match key { + Some(k) => Some(k.to_vec()), + None => None, + }, + bundle: match bundle { + Some(b) => Some(b.to_vec()), + None => None, + }, + } + } + + pub fn cert(&self) -> &OpenSSlX509Cert { + &self.cert + } + + pub fn key(&self) -> Option<&Vec> { + match self.key { + Some(ref k) => Some(&k), + None => None, + } + } + + pub fn bundle(&self) -> Option<&Vec> { + match self.bundle { + Some(ref b) => Some(&b), + None => None, + } + } +} + +impl fmt::Debug for X509 { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let X509 { cert, .. } = self; + write!( + f, + "OpenSSL X509 Certificate: {{ {:?} }}", + cert.to_pem().unwrap_or_else(|_| vec![]) + ) + } +} + +impl SVIDKind for X509 {} + +impl SVID { + pub fn from_pem(pem: &[u8], key: Option, bundle: Option) -> Result> { + let cert = OpenSSlX509Cert::from_pem(pem).chain_err(|| ErrorKind::InvalidPEM)?; + + match SVID::::parse_uri(&cert) { + Ok(uri) => Ok(SVID:: { + doc: X509::new(cert, key, bundle), + uri, + }), + Err(e) => Err(e.chain_err(|| ErrorKind::InvalidSAN)), + } + } + + pub fn from_path(path: &Path, key: Option<&Path>, bundle: Option<&Path>) -> Result> { + let contents = fs::read(path).chain_err(|| path)?; + let cert = + OpenSSlX509Cert::from_pem(contents.as_slice()).chain_err(|| ErrorKind::InvalidPEM)?; + + let key_contents = match key { + Some(path) => Some(fs::read(path).chain_err(|| path)?.to_vec()), + None => None, + }; + let bundle_contents = match bundle { + Some(path) => Some(fs::read(path).chain_err(|| path)?.to_vec()), + None => None, + }; + + match SVID::::parse_uri(&cert) { + Ok(uri) => Ok(SVID:: { + doc: X509::new(cert, key_contents, bundle_contents), + uri, + }), + Err(e) => Err(e.chain_err(|| ErrorKind::InvalidPEM)), + } + } + + pub fn from_der(der: &[u8], key: Option, bundle: Option) -> Result> { + let cert = OpenSSlX509Cert::from_der(der).chain_err(|| ErrorKind::InvalidDER)?; + + match SVID::::parse_uri(&cert) { + Ok(uri) => Ok(SVID:: { + doc: X509::new(cert, key, bundle), + uri, + }), + Err(e) => Err(e.chain_err(|| ErrorKind::InvalidSAN)), + } + } + + pub fn from_x509( + cert: OpenSSlX509Cert, + key: Option, + bundle: Option, + ) -> Result> { + match SVID::::parse_uri(&cert) { + Ok(uri) => Ok(SVID:: { + doc: X509::new(cert, key, bundle), + uri, + }), + Err(e) => Err(e.chain_err(|| ErrorKind::InvalidPEM)), + } + } + + pub fn uri(&self) -> &URI { + let SVID:: { uri, .. } = self; + &uri + } + + pub fn x509(&self) -> &X509 { + let SVID:: { doc, .. } = self; + &doc + } + + pub fn match_spiffe_uri(&self, uri: &str) -> Result { + Ok(self.uri().to_string().eq_ignore_ascii_case(uri)) + } + + fn parse_uri(cert: &OpenSSlX509Cert) -> Result { + let sans = match cert.subject_alt_names() { + Some(val) => val, + None => return Err(ErrorKind::InvalidSAN.into()), + }; + + let mut validated_uri: Option = None; + // Only allows one valid SPIFFE uri in SAN field per SPIFFE specification - returns error if multiple found + for san_entry in sans { + if let Some(uri) = san_entry.uri() { + if let Ok(spiffe_uri) = uri.parse::() { + if let Some(validated_uri) = validated_uri { + return Err(ErrorKind::MultipleURIFound( + validated_uri.to_string(), + uri.to_string(), + ) + .into()); + } + validated_uri = Some(spiffe_uri); + } + } + } + + validated_uri.ok_or_else(|| Error::from(ErrorKind::InvalidSAN)) + } +} + +impl Deref for SVID { + type Target = X509; + + fn deref(&self) -> &X509 { + let SVID:: { doc, .. } = self; + &doc + } +} diff --git a/spiffe/src/uri/mod.rs b/spiffe/src/uri/mod.rs index 30af8e5..9b6e5f9 100644 --- a/spiffe/src/uri/mod.rs +++ b/spiffe/src/uri/mod.rs @@ -1,8 +1,9 @@ -use hyper::Url; +use error_chain::error_chain; use std::str::FromStr; use std::string::ToString; +use url::Url; -error_chain!{ +error_chain! { errors { InvalidURI(uri: String) { description("An error during the parsing of a SPIFFE URI") @@ -13,8 +14,8 @@ error_chain!{ } impl<'a> From<&'a Url> for ErrorKind { - fn from(url: &'a Url) -> Self { - ErrorKind::InvalidURI(url.as_str().to_string()) + fn from(uri: &'a Url) -> Self { + ErrorKind::InvalidURI(uri.to_string()) } } @@ -30,7 +31,7 @@ impl URI { pub fn trust_domain(&self) -> String { // This unwrap should never fail -- if it does, something is wrong and please file bug - self.uri.host_str().unwrap().to_string() + self.uri.host().unwrap().to_string() } pub fn validate_spiffe_uri(uri: Url) -> Result { @@ -44,10 +45,10 @@ impl URI { || (uri.path() == "/") || (uri.path() == "") { - Err(ErrorKind::from(&uri))? + Err(ErrorKind::from(&uri).into()) + } else { + Ok(uri) } - - Ok(uri) } } @@ -64,9 +65,9 @@ impl FromStr for URI { match uri.parse::() { Ok(uri) => match URI::validate_spiffe_uri(uri) { Ok(validated_uri) => Ok(URI { uri: validated_uri }), - Err(e) => Err(e)?, + Err(e) => Err(e), }, - Err(_) => Err(ErrorKind::InvalidURI(uri.to_string()))?, + Err(_) => Err(ErrorKind::InvalidURI(uri.to_string()).into()), } } } diff --git a/spiffe/src/workload/jwt.rs b/spiffe/src/workload/jwt.rs new file mode 100644 index 0000000..dcd772a --- /dev/null +++ b/spiffe/src/workload/jwt.rs @@ -0,0 +1,105 @@ +use crate::svid::jwt::Jwt; +use crate::svid::SVID; +use crate::uri::URI; +use crate::workload::workload_api::{JWTSVIDRequest, ValidateJWTSVIDRequest}; +use crate::workload::workload_api_grpc::SpiffeWorkloadApiClient; +use crate::workload::INITIAL_CONNECTION_TIMEOUT; +use crate::workload::MAX_CLIENT_BACKOFF; +use crate::workload::{ErrorKind, Result, ResultExt}; +use grpcio::{ChannelBuilder, EnvBuilder}; +use log::error; +use std::str::FromStr; +use std::sync::Arc; +use std::time::Duration; + +pub struct JWTClient { + client: SpiffeWorkloadApiClient, + timeout: Duration, +} + +pub struct ValidateResponse { + spiffe_id: URI, + claims: Option, +} + +impl ValidateResponse { + pub fn spiffe_id(&self) -> &URI { + &self.spiffe_id + } + + pub fn claims(&self) -> Option<&protobuf::well_known_types::Struct> { + self.claims.as_ref() + } +} + +pub use protobuf::well_known_types::Struct; + +impl JWTClient { + pub fn new(addr: &str, backoff: Option, timeout: Option) -> JWTClient { + let backoff = backoff.unwrap_or(*MAX_CLIENT_BACKOFF); + let env = Arc::new(EnvBuilder::new().build()); + let channel = ChannelBuilder::new(env) + .initial_reconnect_backoff(backoff) + .max_reconnect_backoff(backoff) + .connect(addr); + JWTClient { + client: SpiffeWorkloadApiClient::new(channel), + timeout: timeout.unwrap_or(*INITIAL_CONNECTION_TIMEOUT), + } + } + + pub fn validate(&self, audience: String, svid: Jwt) -> Result { + let mut metadata = ::grpcio::MetadataBuilder::new(); + metadata + .add_str("workload.spiffe.io", "true") + .chain_err(|| ErrorKind::ClientConfigFailure)?; + + let options = ::grpcio::CallOption::default() + .timeout(self.timeout) + .headers(metadata.build()); + + let mut req = ValidateJWTSVIDRequest::new(); + req.set_audience(audience); + req.set_svid((&svid.svid()).to_string()); + + let res = self + .client + .validate_jwtsvid_opt(&req, options) + .map_err(|e| { + error!("Error during validation: {}.", e); + ErrorKind::ValidateFailure + })?; + + Ok(ValidateResponse { + spiffe_id: URI::from_str(&res.spiffe_id).chain_err(|| ErrorKind::ValidateFailure)?, + claims: res.claims.into_option(), + }) + } + + /// Fetch the first JWT-SVID of the workload + pub fn fetch(&self, audience: String) -> Result> { + let mut metadata = ::grpcio::MetadataBuilder::new(); + metadata + .add_str("workload.spiffe.io", "true") + .chain_err(|| ErrorKind::ClientConfigFailure)?; + + let options = ::grpcio::CallOption::default() + .timeout(self.timeout) + .headers(metadata.build()); + + let mut req = JWTSVIDRequest::new(); + let mut audience_field = protobuf::RepeatedField::new(); + audience_field.push(audience); + req.set_audience(audience_field); + + let mut res = self + .client + .fetch_jwtsvid_opt(&req, options) + .chain_err(|| ErrorKind::FetchFailure)?; + + // Only take the first one. + let svid = res.svids.pop().chain_err(|| ErrorKind::FetchFailure)?; + + SVID::::new(svid.svid, &svid.spiffe_id).chain_err(|| ErrorKind::FetchFailure) + } +} diff --git a/spiffe/src/workload/mod.rs b/spiffe/src/workload/mod.rs index 7b8a6f2..d8c14b2 100644 --- a/spiffe/src/workload/mod.rs +++ b/spiffe/src/workload/mod.rs @@ -1,24 +1,20 @@ -use futures::Future; -use futures::Stream; -use grpcio::{ChannelBuilder, EnvBuilder}; -use std::collections::HashMap; -use std::sync::Arc; -use std::time::Duration; -use std::vec::Vec; -use svid::{Bundle, SVID, X509}; - +pub mod jwt; mod workload_api; mod workload_api_grpc; +pub mod x509; -use self::workload_api::{X509SVIDRequest, X509SVIDResponse}; -use self::workload_api_grpc::SpiffeWorkloadApiClient; +use crate::svid; +use crate::uri; +use error_chain::error_chain; +use lazy_static::lazy_static; +use std::time::Duration; lazy_static! { - static ref INITIAL_CONNECTION_TIMEOUT: Duration = { Duration::new(15, 0) }; - static ref MAX_CLIENT_BACKOFF: Duration = { Duration::new(300, 0) }; + static ref INITIAL_CONNECTION_TIMEOUT: Duration = Duration::new(15, 0); + static ref MAX_CLIENT_BACKOFF: Duration = Duration::new(300, 0); } -error_chain!{ +error_chain! { errors { ClientConfigFailure { description("An error during the configuration of client") @@ -28,126 +24,19 @@ error_chain!{ description("An error during the the fetch of api payload") display("Unable to fetch api payload") } + ValidateFailure { + description("An error during the the validation of api payload") + display("Unable to validate api payload") + } } links { - Uri(::uri::Error, ::uri::ErrorKind); - SVID(::svid::Error, ::svid::ErrorKind); + Uri(uri::Error, uri::ErrorKind); + X509SVID(svid::x509::Error, svid::x509::ErrorKind); + JWTSVID(svid::jwt::Error, svid::jwt::ErrorKind); } foreign_links { - GRPCIO(::grpcio::Error); - } -} - -type CRL = Vec; - -#[derive(Debug)] -pub struct X509Payload { - svids: Vec>, - federated_bundles: HashMap, - crl: Vec, -} - -pub type X509Response = X509SVIDResponse; - -impl X509Payload { - pub fn new(response: X509Response) -> Result { - let mut svids = Vec::>::with_capacity(response.svids.len()); - - for x in response.svids.into_iter() { - let mut svid = SVID::::from_der( - &x.x509_svid, - Some(x.bundle.to_vec()), - Some(x.x509_svid_key.to_vec()), - )?; - - svids.push(svid); - } - - Ok(X509Payload { - svids, - federated_bundles: response.federated_bundles, - crl: response.crl.into_vec(), - }) - } - - pub fn svids(&self) -> &Vec> { - &self.svids - } - - pub fn federated_bundles(&self) -> &HashMap { - &self.federated_bundles - } - - pub fn crl(&self) -> &Vec { - &self.crl - } -} - -pub type X509Stream = ::grpcio::ClientSStreamReceiver<::workload::workload_api::X509SVIDResponse>; - -pub struct X509Client { - client: SpiffeWorkloadApiClient, -} - -impl X509Client { - pub fn new(addr: &str, backoff: Option) -> X509Client { - let backoff = backoff.unwrap_or(*MAX_CLIENT_BACKOFF); - let env = Arc::new(EnvBuilder::new().build()); - let channel = ChannelBuilder::new(env) - .initial_reconnect_backoff(backoff) - .max_reconnect_backoff(backoff) - .connect(addr); - X509Client { - client: SpiffeWorkloadApiClient::new(channel), - } - } - - pub fn fetch(&self, timeout: Option) -> Result> { - let mut metadata = ::grpcio::MetadataBuilder::new(); - metadata - .add_str("workload.spiffe.io", "true") - .chain_err(|| ErrorKind::ClientConfigFailure)?; - - let options = ::grpcio::CallOption::default() - .timeout(timeout.unwrap_or(*INITIAL_CONNECTION_TIMEOUT)) - .headers(metadata.build()); - - let rx = self - .client - .fetch_x509_svid_opt(&X509SVIDRequest::new(), options) - .chain_err(|| ErrorKind::ClientConfigFailure)?; - - let items = rx.take(1).collect().wait(); - - match items { - Ok(mut item) => { - if let Some(val) = item.pop() { - Ok(X509Payload::new(val)) - } else { - Err(ErrorKind::FetchFailure)? - } - } - Err(e) => Err(Error::with_chain(e, ErrorKind::FetchFailure))?, - } - } - - pub fn stream(&self, timeout: Option) -> Result { - let mut metadata = ::grpcio::MetadataBuilder::new(); - metadata - .add_str("workload.spiffe.io", "true") - .chain_err(|| ErrorKind::ClientConfigFailure)?; - - let options = ::grpcio::CallOption::default() - .timeout(timeout.unwrap_or(*INITIAL_CONNECTION_TIMEOUT)) - .headers(metadata.build()); - - let rx = self - .client - .fetch_x509_svid_opt(&X509SVIDRequest::new(), options) - .chain_err(|| ErrorKind::ClientConfigFailure)?; - - Ok(rx) + GRPCIO(grpcio::Error); } } diff --git a/spiffe/src/workload/workload_api.proto b/spiffe/src/workload/workload_api.proto index 9a13c0c..cab8b5c 100644 --- a/spiffe/src/workload/workload_api.proto +++ b/spiffe/src/workload/workload_api.proto @@ -1,14 +1,10 @@ +// Taken from https://github.com/spiffe/go-spiffe/blob/master/proto/spiffe/workload/workload.proto + syntax = "proto3"; -message X509SVIDRequest { } +import "google/protobuf/struct.proto"; -service SpiffeWorkloadAPI { - // X.509-SVID Profile - // Fetch all SPIFFE identities the workload is entitled to, as - // well as related information like trust bundles and CRLs. As - // this information changes, subsequent messages will be sent. - rpc FetchX509SVID(X509SVIDRequest) returns (stream X509SVIDResponse); -} +message X509SVIDRequest { } // The X509SVIDResponse message carries a set of X.509 SVIDs and their // associated information. It also carries a set of global CRLs, and a @@ -31,8 +27,7 @@ message X509SVIDResponse { // The X509SVID message carries a single SVID and all associated // information, including CA bundles. message X509SVID { - // The SPIFFE ID of the SVID in this entry. MUST match the SPIFFE ID - // encoded in the `x509_svid` certificate. + // The SPIFFE ID of the SVID in this entry string spiffe_id = 1; // ASN.1 DER encoded certificate chain. MAY include intermediates, @@ -45,5 +40,55 @@ message X509SVID { // CA certificates belonging to the Trust Domain // ASN.1 DER encoded bytes bundle = 4; +} + +message JWTSVID { + string spiffe_id = 1; + + // Encoded using JWS Compact Serialization + string svid = 2; +} -} \ No newline at end of file +message JWTSVIDRequest { + repeated string audience = 1; + + // SPIFFE ID of the JWT being requested + // If not set, all IDs will be returned + string spiffe_id = 2; +} + +message JWTSVIDResponse { + repeated JWTSVID svids = 1; +} + +message JWTBundlesRequest { } + +message JWTBundlesResponse { + // JWK sets, keyed by trust domain URI + map bundles = 1; +} + +message ValidateJWTSVIDRequest { + string audience = 1; + + // Encoded using JWS Compact Serialization + string svid = 2; +} + +message ValidateJWTSVIDResponse { + string spiffe_id = 1; + google.protobuf.Struct claims = 2; +} + +service SpiffeWorkloadAPI { + // JWT-SVID Profile + rpc FetchJWTSVID(JWTSVIDRequest) returns (JWTSVIDResponse); + rpc FetchJWTBundles(JWTBundlesRequest) returns (stream JWTBundlesResponse); + rpc ValidateJWTSVID(ValidateJWTSVIDRequest) returns (ValidateJWTSVIDResponse); + + // X.509-SVID Profile + // Fetch all SPIFFE identities the workload is entitled to, as + // well as related information like trust bundles and CRLs. As + // this information changes, subsequent messages will be sent. + rpc FetchX509SVID(X509SVIDRequest) returns (stream X509SVIDResponse); +} diff --git a/spiffe/src/workload/workload_api.rs b/spiffe/src/workload/workload_api.rs index 7d66ef2..7564bd6 100644 --- a/spiffe/src/workload/workload_api.rs +++ b/spiffe/src/workload/workload_api.rs @@ -1,11 +1,12 @@ -// This file is generated by rust-protobuf 2.0.5. Do not edit +// This file is generated by rust-protobuf 2.18.0. Do not edit // @generated -// https://github.com/Manishearth/rust-clippy/issues/702 +// https://github.com/rust-lang/rust-clippy/issues/702 #![allow(unknown_lints)] -#![allow(clippy)] +#![allow(clippy::all)] -#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_attributes)] +#![rustfmt::skip] #![allow(box_pointers)] #![allow(dead_code)] @@ -14,18 +15,25 @@ #![allow(non_snake_case)] #![allow(non_upper_case_globals)] #![allow(trivial_casts)] -#![allow(unsafe_code)] #![allow(unused_imports)] #![allow(unused_results)] +//! Generated file from `src/workload/workload_api.proto` -use protobuf::Message as Message_imported_for_functions; -use protobuf::ProtobufEnum as ProtobufEnum_imported_for_functions; +/// Generated files are compatible only with the same version +/// of protobuf runtime. +// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_18_0; #[derive(PartialEq,Clone,Default)] pub struct X509SVIDRequest { // special fields - unknown_fields: ::protobuf::UnknownFields, - cached_size: ::protobuf::CachedSize, + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a X509SVIDRequest { + fn default() -> &'a X509SVIDRequest { + ::default_instance() + } } impl X509SVIDRequest { @@ -39,7 +47,7 @@ impl ::protobuf::Message for X509SVIDRequest { true } - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> { + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { while !is.eof()? { let (field_number, wire_type) = is.read_tag_unpack()?; match field_number { @@ -60,7 +68,7 @@ impl ::protobuf::Message for X509SVIDRequest { my_size } - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> { + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) } @@ -77,13 +85,13 @@ impl ::protobuf::Message for X509SVIDRequest { &mut self.unknown_fields } - fn as_any(&self) -> &::std::any::Any { - self as &::std::any::Any + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) } - fn as_any_mut(&mut self) -> &mut ::std::any::Any { - self as &mut ::std::any::Any + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) } - fn into_any(self: Box) -> ::std::boxed::Box<::std::any::Any> { + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { self } @@ -96,30 +104,20 @@ impl ::protobuf::Message for X509SVIDRequest { } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const ::protobuf::reflect::MessageDescriptor, - }; - unsafe { - descriptor.get(|| { - let fields = ::std::vec::Vec::new(); - ::protobuf::reflect::MessageDescriptor::new::( - "X509SVIDRequest", - fields, - file_descriptor_proto() - ) - }) - } + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let fields = ::std::vec::Vec::new(); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "X509SVIDRequest", + fields, + file_descriptor_proto() + ) + }) } fn default_instance() -> &'static X509SVIDRequest { - static mut instance: ::protobuf::lazy::Lazy = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const X509SVIDRequest, - }; - unsafe { - instance.get(X509SVIDRequest::new) - } + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(X509SVIDRequest::new) } } @@ -130,14 +128,14 @@ impl ::protobuf::Clear for X509SVIDRequest { } impl ::std::fmt::Debug for X509SVIDRequest { - fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } impl ::protobuf::reflect::ProtobufValue for X509SVIDRequest { - fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { - ::protobuf::reflect::ProtobufValueRef::Message(self) + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) } } @@ -148,8 +146,14 @@ pub struct X509SVIDResponse { pub crl: ::protobuf::RepeatedField<::std::vec::Vec>, pub federated_bundles: ::std::collections::HashMap<::std::string::String, ::std::vec::Vec>, // special fields - unknown_fields: ::protobuf::UnknownFields, - cached_size: ::protobuf::CachedSize, + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a X509SVIDResponse { + fn default() -> &'a X509SVIDResponse { + ::default_instance() + } } impl X509SVIDResponse { @@ -159,6 +163,10 @@ impl X509SVIDResponse { // repeated .X509SVID svids = 1; + + pub fn get_svids(&self) -> &[X509SVID] { + &self.svids + } pub fn clear_svids(&mut self) { self.svids.clear(); } @@ -178,12 +186,12 @@ impl X509SVIDResponse { ::std::mem::replace(&mut self.svids, ::protobuf::RepeatedField::new()) } - pub fn get_svids(&self) -> &[X509SVID] { - &self.svids - } - // repeated bytes crl = 2; + + pub fn get_crl(&self) -> &[::std::vec::Vec] { + &self.crl + } pub fn clear_crl(&mut self) { self.crl.clear(); } @@ -203,12 +211,12 @@ impl X509SVIDResponse { ::std::mem::replace(&mut self.crl, ::protobuf::RepeatedField::new()) } - pub fn get_crl(&self) -> &[::std::vec::Vec] { - &self.crl - } - // repeated .X509SVIDResponse.FederatedBundlesEntry federated_bundles = 3; + + pub fn get_federated_bundles(&self) -> &::std::collections::HashMap<::std::string::String, ::std::vec::Vec> { + &self.federated_bundles + } pub fn clear_federated_bundles(&mut self) { self.federated_bundles.clear(); } @@ -227,10 +235,6 @@ impl X509SVIDResponse { pub fn take_federated_bundles(&mut self) -> ::std::collections::HashMap<::std::string::String, ::std::vec::Vec> { ::std::mem::replace(&mut self.federated_bundles, ::std::collections::HashMap::new()) } - - pub fn get_federated_bundles(&self) -> &::std::collections::HashMap<::std::string::String, ::std::vec::Vec> { - &self.federated_bundles - } } impl ::protobuf::Message for X509SVIDResponse { @@ -243,7 +247,7 @@ impl ::protobuf::Message for X509SVIDResponse { true } - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> { + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { while !is.eof()? { let (field_number, wire_type) = is.read_tag_unpack()?; match field_number { @@ -281,7 +285,7 @@ impl ::protobuf::Message for X509SVIDResponse { my_size } - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> { + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { for v in &self.svids { os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; os.write_raw_varint32(v.get_cached_size())?; @@ -307,13 +311,13 @@ impl ::protobuf::Message for X509SVIDResponse { &mut self.unknown_fields } - fn as_any(&self) -> &::std::any::Any { - self as &::std::any::Any + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) } - fn as_any_mut(&mut self) -> &mut ::std::any::Any { - self as &mut ::std::any::Any + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) } - fn into_any(self: Box) -> ::std::boxed::Box<::std::any::Any> { + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { self } @@ -326,66 +330,56 @@ impl ::protobuf::Message for X509SVIDResponse { } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const ::protobuf::reflect::MessageDescriptor, - }; - unsafe { - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "svids", - |m: &X509SVIDResponse| { &m.svids }, - |m: &mut X509SVIDResponse| { &mut m.svids }, - )); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>( - "crl", - |m: &X509SVIDResponse| { &m.crl }, - |m: &mut X509SVIDResponse| { &mut m.crl }, - )); - fields.push(::protobuf::reflect::accessor::make_map_accessor::<_, ::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeBytes>( - "federated_bundles", - |m: &X509SVIDResponse| { &m.federated_bundles }, - |m: &mut X509SVIDResponse| { &mut m.federated_bundles }, - )); - ::protobuf::reflect::MessageDescriptor::new::( - "X509SVIDResponse", - fields, - file_descriptor_proto() - ) - }) - } + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "svids", + |m: &X509SVIDResponse| { &m.svids }, + |m: &mut X509SVIDResponse| { &mut m.svids }, + )); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>( + "crl", + |m: &X509SVIDResponse| { &m.crl }, + |m: &mut X509SVIDResponse| { &mut m.crl }, + )); + fields.push(::protobuf::reflect::accessor::make_map_accessor::<_, ::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeBytes>( + "federated_bundles", + |m: &X509SVIDResponse| { &m.federated_bundles }, + |m: &mut X509SVIDResponse| { &mut m.federated_bundles }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "X509SVIDResponse", + fields, + file_descriptor_proto() + ) + }) } fn default_instance() -> &'static X509SVIDResponse { - static mut instance: ::protobuf::lazy::Lazy = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const X509SVIDResponse, - }; - unsafe { - instance.get(X509SVIDResponse::new) - } + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(X509SVIDResponse::new) } } impl ::protobuf::Clear for X509SVIDResponse { fn clear(&mut self) { - self.clear_svids(); - self.clear_crl(); - self.clear_federated_bundles(); + self.svids.clear(); + self.crl.clear(); + self.federated_bundles.clear(); self.unknown_fields.clear(); } } impl ::std::fmt::Debug for X509SVIDResponse { - fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } impl ::protobuf::reflect::ProtobufValue for X509SVIDResponse { - fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { - ::protobuf::reflect::ProtobufValueRef::Message(self) + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) } } @@ -397,8 +391,14 @@ pub struct X509SVID { pub x509_svid_key: ::std::vec::Vec, pub bundle: ::std::vec::Vec, // special fields - unknown_fields: ::protobuf::UnknownFields, - cached_size: ::protobuf::CachedSize, + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a X509SVID { + fn default() -> &'a X509SVID { + ::default_instance() + } } impl X509SVID { @@ -408,6 +408,10 @@ impl X509SVID { // string spiffe_id = 1; + + pub fn get_spiffe_id(&self) -> &str { + &self.spiffe_id + } pub fn clear_spiffe_id(&mut self) { self.spiffe_id.clear(); } @@ -428,12 +432,12 @@ impl X509SVID { ::std::mem::replace(&mut self.spiffe_id, ::std::string::String::new()) } - pub fn get_spiffe_id(&self) -> &str { - &self.spiffe_id - } - // bytes x509_svid = 2; + + pub fn get_x509_svid(&self) -> &[u8] { + &self.x509_svid + } pub fn clear_x509_svid(&mut self) { self.x509_svid.clear(); } @@ -454,12 +458,12 @@ impl X509SVID { ::std::mem::replace(&mut self.x509_svid, ::std::vec::Vec::new()) } - pub fn get_x509_svid(&self) -> &[u8] { - &self.x509_svid - } - // bytes x509_svid_key = 3; + + pub fn get_x509_svid_key(&self) -> &[u8] { + &self.x509_svid_key + } pub fn clear_x509_svid_key(&mut self) { self.x509_svid_key.clear(); } @@ -480,12 +484,12 @@ impl X509SVID { ::std::mem::replace(&mut self.x509_svid_key, ::std::vec::Vec::new()) } - pub fn get_x509_svid_key(&self) -> &[u8] { - &self.x509_svid_key - } - // bytes bundle = 4; + + pub fn get_bundle(&self) -> &[u8] { + &self.bundle + } pub fn clear_bundle(&mut self) { self.bundle.clear(); } @@ -505,10 +509,6 @@ impl X509SVID { pub fn take_bundle(&mut self) -> ::std::vec::Vec { ::std::mem::replace(&mut self.bundle, ::std::vec::Vec::new()) } - - pub fn get_bundle(&self) -> &[u8] { - &self.bundle - } } impl ::protobuf::Message for X509SVID { @@ -516,7 +516,7 @@ impl ::protobuf::Message for X509SVID { true } - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> { + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { while !is.eof()? { let (field_number, wire_type) = is.read_tag_unpack()?; match field_number { @@ -561,7 +561,7 @@ impl ::protobuf::Message for X509SVID { my_size } - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> { + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { if !self.spiffe_id.is_empty() { os.write_string(1, &self.spiffe_id)?; } @@ -590,13 +590,13 @@ impl ::protobuf::Message for X509SVID { &mut self.unknown_fields } - fn as_any(&self) -> &::std::any::Any { - self as &::std::any::Any + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) } - fn as_any_mut(&mut self) -> &mut ::std::any::Any { - self as &mut ::std::any::Any + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) } - fn into_any(self: Box) -> ::std::boxed::Box<::std::any::Any> { + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { self } @@ -609,161 +609,1461 @@ impl ::protobuf::Message for X509SVID { } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const ::protobuf::reflect::MessageDescriptor, - }; - unsafe { - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "spiffe_id", - |m: &X509SVID| { &m.spiffe_id }, - |m: &mut X509SVID| { &mut m.spiffe_id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>( - "x509_svid", - |m: &X509SVID| { &m.x509_svid }, - |m: &mut X509SVID| { &mut m.x509_svid }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>( - "x509_svid_key", - |m: &X509SVID| { &m.x509_svid_key }, - |m: &mut X509SVID| { &mut m.x509_svid_key }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>( - "bundle", - |m: &X509SVID| { &m.bundle }, - |m: &mut X509SVID| { &mut m.bundle }, - )); - ::protobuf::reflect::MessageDescriptor::new::( - "X509SVID", - fields, - file_descriptor_proto() - ) - }) - } + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "spiffe_id", + |m: &X509SVID| { &m.spiffe_id }, + |m: &mut X509SVID| { &mut m.spiffe_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>( + "x509_svid", + |m: &X509SVID| { &m.x509_svid }, + |m: &mut X509SVID| { &mut m.x509_svid }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>( + "x509_svid_key", + |m: &X509SVID| { &m.x509_svid_key }, + |m: &mut X509SVID| { &mut m.x509_svid_key }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>( + "bundle", + |m: &X509SVID| { &m.bundle }, + |m: &mut X509SVID| { &mut m.bundle }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "X509SVID", + fields, + file_descriptor_proto() + ) + }) } fn default_instance() -> &'static X509SVID { - static mut instance: ::protobuf::lazy::Lazy = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const X509SVID, - }; - unsafe { - instance.get(X509SVID::new) - } + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(X509SVID::new) } } impl ::protobuf::Clear for X509SVID { fn clear(&mut self) { - self.clear_spiffe_id(); - self.clear_x509_svid(); - self.clear_x509_svid_key(); - self.clear_bundle(); + self.spiffe_id.clear(); + self.x509_svid.clear(); + self.x509_svid_key.clear(); + self.bundle.clear(); self.unknown_fields.clear(); } } impl ::std::fmt::Debug for X509SVID { - fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } impl ::protobuf::reflect::ProtobufValue for X509SVID { - fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { - ::protobuf::reflect::ProtobufValueRef::Message(self) + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) } } -static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x1asrc/api/workload_api.proto\"\x11\n\x0fX509SVIDRequest\"\xe0\x01\n\ - \x10X509SVIDResponse\x12\x1f\n\x05svids\x18\x01\x20\x03(\x0b2\t.X509SVID\ - R\x05svids\x12\x10\n\x03crl\x18\x02\x20\x03(\x0cR\x03crl\x12T\n\x11feder\ - ated_bundles\x18\x03\x20\x03(\x0b2'.X509SVIDResponse.FederatedBundlesEnt\ - ryR\x10federatedBundles\x1aC\n\x15FederatedBundlesEntry\x12\x10\n\x03key\ - \x18\x01\x20\x01(\tR\x03key\x12\x14\n\x05value\x18\x02\x20\x01(\x0cR\x05\ - value:\x028\x01\"\x80\x01\n\x08X509SVID\x12\x1b\n\tspiffe_id\x18\x01\x20\ - \x01(\tR\x08spiffeId\x12\x1b\n\tx509_svid\x18\x02\x20\x01(\x0cR\x08x509S\ - vid\x12\"\n\rx509_svid_key\x18\x03\x20\x01(\x0cR\x0bx509SvidKey\x12\x16\ - \n\x06bundle\x18\x04\x20\x01(\x0cR\x06bundle2K\n\x11SpiffeWorkloadAPI\ - \x126\n\rFetchX509SVID\x12\x10.X509SVIDRequest\x1a\x11.X509SVIDResponse0\ - \x01J\xdb\x0e\n\x06\x12\x04\0\00\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\t\ - \n\x02\x04\0\x12\x03\x02\0\x1c\n\n\n\x03\x04\0\x01\x12\x03\x02\x08\x17\n\ - \n\n\x02\x06\0\x12\x04\x04\0\n\x01\n\n\n\x03\x06\0\x01\x12\x03\x04\x08\ - \x19\n\xd9\x01\n\x04\x06\0\x02\0\x12\x03\t\x04I\x1a\xcb\x01\x20X.509-SVI\ - D\x20Profile\n\x20Fetch\x20all\x20SPIFFE\x20identities\x20the\x20workloa\ - d\x20is\x20entitled\x20to,\x20as\n\x20well\x20as\x20related\x20informati\ - on\x20like\x20trust\x20bundles\x20and\x20CRLs.\x20As\n\x20this\x20inform\ - ation\x20changes,\x20subsequent\x20messages\x20will\x20be\x20sent.\n\n\ - \x0c\n\x05\x06\0\x02\0\x01\x12\x03\t\x08\x15\n\x0c\n\x05\x06\0\x02\0\x02\ - \x12\x03\t\x16%\n\x0c\n\x05\x06\0\x02\0\x06\x12\x03\t06\n\x0c\n\x05\x06\ - \0\x02\0\x03\x12\x03\t7G\n\xd3\x01\n\x02\x04\x01\x12\x04\x0f\0\x1c\x01\ - \x1a\xc6\x01\x20The\x20X509SVIDResponse\x20message\x20carries\x20a\x20se\ - t\x20of\x20X.509\x20SVIDs\x20and\x20their\n\x20associated\x20information\ - .\x20It\x20also\x20carries\x20a\x20set\x20of\x20global\x20CRLs,\x20and\ - \x20a\n\x20TTL\x20to\x20inform\x20the\x20workload\x20when\x20it\x20shoul\ - d\x20check\x20back\x20next.\n\n\n\n\x03\x04\x01\x01\x12\x03\x0f\x08\x18\ - \n\x9a\x01\n\x04\x04\x01\x02\0\x12\x03\x13\x04\x20\x1a\x8c\x01\x20A\x20l\ - ist\x20of\x20X509SVID\x20messages,\x20each\x20of\x20which\x20includes\ - \x20a\x20single\n\x20SPIFFE\x20Verifiable\x20Identity\x20Document,\x20al\ - ong\x20with\x20its\x20private\x20key\n\x20and\x20bundle.\n\n\x0c\n\x05\ - \x04\x01\x02\0\x04\x12\x03\x13\x04\x0c\n\x0c\n\x05\x04\x01\x02\0\x06\x12\ - \x03\x13\r\x15\n\x0c\n\x05\x04\x01\x02\0\x01\x12\x03\x13\x16\x1b\n\x0c\n\ - \x05\x04\x01\x02\0\x03\x12\x03\x13\x1e\x1f\n\x20\n\x04\x04\x01\x02\x01\ - \x12\x03\x16\x04\x1b\x1a\x13\x20ASN.1\x20DER\x20encoded\n\n\x0c\n\x05\ - \x04\x01\x02\x01\x04\x12\x03\x16\x04\x0c\n\x0c\n\x05\x04\x01\x02\x01\x05\ - \x12\x03\x16\r\x12\n\x0c\n\x05\x04\x01\x02\x01\x01\x12\x03\x16\x13\x16\n\ - \x0c\n\x05\x04\x01\x02\x01\x03\x12\x03\x16\x19\x1a\n\xb8\x01\n\x04\x04\ - \x01\x02\x02\x12\x03\x1b\x04-\x1a\xaa\x01\x20CA\x20certificate\x20bundle\ - s\x20belonging\x20to\x20foreign\x20Trust\x20Domains\x20that\x20the\n\x20\ - workload\x20should\x20trust,\x20keyed\x20by\x20the\x20SPIFFE\x20ID\x20of\ - \x20the\x20foreign\n\x20domain.\x20Bundles\x20are\x20ASN.1\x20DER\x20enc\ - oded.\n\n\r\n\x05\x04\x01\x02\x02\x04\x12\x04\x1b\x04\x16\x1b\n\x0c\n\ - \x05\x04\x01\x02\x02\x06\x12\x03\x1b\x04\x16\n\x0c\n\x05\x04\x01\x02\x02\ - \x01\x12\x03\x1b\x17(\n\x0c\n\x05\x04\x01\x02\x02\x03\x12\x03\x1b+,\no\n\ - \x02\x04\x02\x12\x04\x20\00\x01\x1ac\x20The\x20X509SVID\x20message\x20ca\ - rries\x20a\x20single\x20SVID\x20and\x20all\x20associated\n\x20informatio\ - n,\x20including\x20CA\x20bundles.\n\n\n\n\x03\x04\x02\x01\x12\x03\x20\ - \x08\x10\ny\n\x04\x04\x02\x02\0\x12\x03#\x04\x19\x1al\x20The\x20SPIFFE\ - \x20ID\x20of\x20the\x20SVID\x20in\x20this\x20entry.\x20MUST\x20match\x20\ - the\x20SPIFFE\x20ID\n\x20encoded\x20in\x20the\x20`x509_svid`\x20certific\ - ate.\n\n\r\n\x05\x04\x02\x02\0\x04\x12\x04#\x04\x20\x12\n\x0c\n\x05\x04\ - \x02\x02\0\x05\x12\x03#\x04\n\n\x0c\n\x05\x04\x02\x02\0\x01\x12\x03#\x0b\ - \x14\n\x0c\n\x05\x04\x02\x02\0\x03\x12\x03#\x17\x18\n\x86\x01\n\x04\x04\ - \x02\x02\x01\x12\x03'\x04\x18\x1ay\x20ASN.1\x20DER\x20encoded\x20certifi\ - cate\x20chain.\x20MAY\x20include\x20intermediates,\n\x20the\x20leaf\x20c\ - ertificate\x20(or\x20SVID\x20itself)\x20MUST\x20come\x20first.\n\n\r\n\ - \x05\x04\x02\x02\x01\x04\x12\x04'\x04#\x19\n\x0c\n\x05\x04\x02\x02\x01\ - \x05\x12\x03'\x04\t\n\x0c\n\x05\x04\x02\x02\x01\x01\x12\x03'\n\x13\n\x0c\ - \n\x05\x04\x02\x02\x01\x03\x12\x03'\x16\x17\nI\n\x04\x04\x02\x02\x02\x12\ - \x03*\x04\x1c\x1a<\x20ASN.1\x20DER\x20encoded\x20PKCS#8\x20private\x20ke\ - y.\x20MUST\x20be\x20unencrypted.\n\n\r\n\x05\x04\x02\x02\x02\x04\x12\x04\ - *\x04'\x18\n\x0c\n\x05\x04\x02\x02\x02\x05\x12\x03*\x04\t\n\x0c\n\x05\ - \x04\x02\x02\x02\x01\x12\x03*\n\x17\n\x0c\n\x05\x04\x02\x02\x02\x03\x12\ - \x03*\x1a\x1b\nO\n\x04\x04\x02\x02\x03\x12\x03.\x04\x15\x1aB\x20CA\x20ce\ - rtificates\x20belonging\x20to\x20the\x20Trust\x20Domain\n\x20ASN.1\x20DE\ - R\x20encoded\n\n\r\n\x05\x04\x02\x02\x03\x04\x12\x04.\x04*\x1c\n\x0c\n\ - \x05\x04\x02\x02\x03\x05\x12\x03.\x04\t\n\x0c\n\x05\x04\x02\x02\x03\x01\ - \x12\x03.\n\x10\n\x0c\n\x05\x04\x02\x02\x03\x03\x12\x03.\x13\x14b\x06pro\ - to3\ -"; +#[derive(PartialEq,Clone,Default)] +pub struct JWTSVID { + // message fields + pub spiffe_id: ::std::string::String, + pub svid: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a JWTSVID { + fn default() -> &'a JWTSVID { + ::default_instance() + } +} -static mut file_descriptor_proto_lazy: ::protobuf::lazy::Lazy<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const ::protobuf::descriptor::FileDescriptorProto, -}; +impl JWTSVID { + pub fn new() -> JWTSVID { + ::std::default::Default::default() + } -fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto { - ::protobuf::parse_from_bytes(file_descriptor_proto_data).unwrap() + // string spiffe_id = 1; + + + pub fn get_spiffe_id(&self) -> &str { + &self.spiffe_id + } + pub fn clear_spiffe_id(&mut self) { + self.spiffe_id.clear(); + } + + // Param is passed by value, moved + pub fn set_spiffe_id(&mut self, v: ::std::string::String) { + self.spiffe_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_spiffe_id(&mut self) -> &mut ::std::string::String { + &mut self.spiffe_id + } + + // Take field + pub fn take_spiffe_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.spiffe_id, ::std::string::String::new()) + } + + // string svid = 2; + + + pub fn get_svid(&self) -> &str { + &self.svid + } + pub fn clear_svid(&mut self) { + self.svid.clear(); + } + + // Param is passed by value, moved + pub fn set_svid(&mut self, v: ::std::string::String) { + self.svid = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_svid(&mut self) -> &mut ::std::string::String { + &mut self.svid + } + + // Take field + pub fn take_svid(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.svid, ::std::string::String::new()) + } } -pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { - unsafe { - file_descriptor_proto_lazy.get(|| { - parse_descriptor_proto() +impl ::protobuf::Message for JWTSVID { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.spiffe_id)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.svid)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.spiffe_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.spiffe_id); + } + if !self.svid.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.svid); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.spiffe_id.is_empty() { + os.write_string(1, &self.spiffe_id)?; + } + if !self.svid.is_empty() { + os.write_string(2, &self.svid)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> JWTSVID { + JWTSVID::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "spiffe_id", + |m: &JWTSVID| { &m.spiffe_id }, + |m: &mut JWTSVID| { &mut m.spiffe_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "svid", + |m: &JWTSVID| { &m.svid }, + |m: &mut JWTSVID| { &mut m.svid }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "JWTSVID", + fields, + file_descriptor_proto() + ) }) } + + fn default_instance() -> &'static JWTSVID { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(JWTSVID::new) + } +} + +impl ::protobuf::Clear for JWTSVID { + fn clear(&mut self) { + self.spiffe_id.clear(); + self.svid.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for JWTSVID { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for JWTSVID { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct JWTSVIDRequest { + // message fields + pub audience: ::protobuf::RepeatedField<::std::string::String>, + pub spiffe_id: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a JWTSVIDRequest { + fn default() -> &'a JWTSVIDRequest { + ::default_instance() + } +} + +impl JWTSVIDRequest { + pub fn new() -> JWTSVIDRequest { + ::std::default::Default::default() + } + + // repeated string audience = 1; + + + pub fn get_audience(&self) -> &[::std::string::String] { + &self.audience + } + pub fn clear_audience(&mut self) { + self.audience.clear(); + } + + // Param is passed by value, moved + pub fn set_audience(&mut self, v: ::protobuf::RepeatedField<::std::string::String>) { + self.audience = v; + } + + // Mutable pointer to the field. + pub fn mut_audience(&mut self) -> &mut ::protobuf::RepeatedField<::std::string::String> { + &mut self.audience + } + + // Take field + pub fn take_audience(&mut self) -> ::protobuf::RepeatedField<::std::string::String> { + ::std::mem::replace(&mut self.audience, ::protobuf::RepeatedField::new()) + } + + // string spiffe_id = 2; + + + pub fn get_spiffe_id(&self) -> &str { + &self.spiffe_id + } + pub fn clear_spiffe_id(&mut self) { + self.spiffe_id.clear(); + } + + // Param is passed by value, moved + pub fn set_spiffe_id(&mut self, v: ::std::string::String) { + self.spiffe_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_spiffe_id(&mut self) -> &mut ::std::string::String { + &mut self.spiffe_id + } + + // Take field + pub fn take_spiffe_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.spiffe_id, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for JWTSVIDRequest { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_repeated_string_into(wire_type, is, &mut self.audience)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.spiffe_id)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + for value in &self.audience { + my_size += ::protobuf::rt::string_size(1, &value); + }; + if !self.spiffe_id.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.spiffe_id); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + for v in &self.audience { + os.write_string(1, &v)?; + }; + if !self.spiffe_id.is_empty() { + os.write_string(2, &self.spiffe_id)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> JWTSVIDRequest { + JWTSVIDRequest::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "audience", + |m: &JWTSVIDRequest| { &m.audience }, + |m: &mut JWTSVIDRequest| { &mut m.audience }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "spiffe_id", + |m: &JWTSVIDRequest| { &m.spiffe_id }, + |m: &mut JWTSVIDRequest| { &mut m.spiffe_id }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "JWTSVIDRequest", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static JWTSVIDRequest { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(JWTSVIDRequest::new) + } +} + +impl ::protobuf::Clear for JWTSVIDRequest { + fn clear(&mut self) { + self.audience.clear(); + self.spiffe_id.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for JWTSVIDRequest { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for JWTSVIDRequest { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct JWTSVIDResponse { + // message fields + pub svids: ::protobuf::RepeatedField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a JWTSVIDResponse { + fn default() -> &'a JWTSVIDResponse { + ::default_instance() + } +} + +impl JWTSVIDResponse { + pub fn new() -> JWTSVIDResponse { + ::std::default::Default::default() + } + + // repeated .JWTSVID svids = 1; + + + pub fn get_svids(&self) -> &[JWTSVID] { + &self.svids + } + pub fn clear_svids(&mut self) { + self.svids.clear(); + } + + // Param is passed by value, moved + pub fn set_svids(&mut self, v: ::protobuf::RepeatedField) { + self.svids = v; + } + + // Mutable pointer to the field. + pub fn mut_svids(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.svids + } + + // Take field + pub fn take_svids(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.svids, ::protobuf::RepeatedField::new()) + } +} + +impl ::protobuf::Message for JWTSVIDResponse { + fn is_initialized(&self) -> bool { + for v in &self.svids { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.svids)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + for value in &self.svids { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + for v in &self.svids { + os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> JWTSVIDResponse { + JWTSVIDResponse::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "svids", + |m: &JWTSVIDResponse| { &m.svids }, + |m: &mut JWTSVIDResponse| { &mut m.svids }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "JWTSVIDResponse", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static JWTSVIDResponse { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(JWTSVIDResponse::new) + } +} + +impl ::protobuf::Clear for JWTSVIDResponse { + fn clear(&mut self) { + self.svids.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for JWTSVIDResponse { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for JWTSVIDResponse { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct JWTBundlesRequest { + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a JWTBundlesRequest { + fn default() -> &'a JWTBundlesRequest { + ::default_instance() + } +} + +impl JWTBundlesRequest { + pub fn new() -> JWTBundlesRequest { + ::std::default::Default::default() + } +} + +impl ::protobuf::Message for JWTBundlesRequest { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> JWTBundlesRequest { + JWTBundlesRequest::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let fields = ::std::vec::Vec::new(); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "JWTBundlesRequest", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static JWTBundlesRequest { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(JWTBundlesRequest::new) + } +} + +impl ::protobuf::Clear for JWTBundlesRequest { + fn clear(&mut self) { + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for JWTBundlesRequest { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for JWTBundlesRequest { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct JWTBundlesResponse { + // message fields + pub bundles: ::std::collections::HashMap<::std::string::String, ::std::vec::Vec>, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a JWTBundlesResponse { + fn default() -> &'a JWTBundlesResponse { + ::default_instance() + } +} + +impl JWTBundlesResponse { + pub fn new() -> JWTBundlesResponse { + ::std::default::Default::default() + } + + // repeated .JWTBundlesResponse.BundlesEntry bundles = 1; + + + pub fn get_bundles(&self) -> &::std::collections::HashMap<::std::string::String, ::std::vec::Vec> { + &self.bundles + } + pub fn clear_bundles(&mut self) { + self.bundles.clear(); + } + + // Param is passed by value, moved + pub fn set_bundles(&mut self, v: ::std::collections::HashMap<::std::string::String, ::std::vec::Vec>) { + self.bundles = v; + } + + // Mutable pointer to the field. + pub fn mut_bundles(&mut self) -> &mut ::std::collections::HashMap<::std::string::String, ::std::vec::Vec> { + &mut self.bundles + } + + // Take field + pub fn take_bundles(&mut self) -> ::std::collections::HashMap<::std::string::String, ::std::vec::Vec> { + ::std::mem::replace(&mut self.bundles, ::std::collections::HashMap::new()) + } +} + +impl ::protobuf::Message for JWTBundlesResponse { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_map_into::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeBytes>(wire_type, is, &mut self.bundles)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + my_size += ::protobuf::rt::compute_map_size::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeBytes>(1, &self.bundles); + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + ::protobuf::rt::write_map_with_cached_sizes::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeBytes>(1, &self.bundles, os)?; + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> JWTBundlesResponse { + JWTBundlesResponse::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_map_accessor::<_, ::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeBytes>( + "bundles", + |m: &JWTBundlesResponse| { &m.bundles }, + |m: &mut JWTBundlesResponse| { &mut m.bundles }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "JWTBundlesResponse", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static JWTBundlesResponse { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(JWTBundlesResponse::new) + } +} + +impl ::protobuf::Clear for JWTBundlesResponse { + fn clear(&mut self) { + self.bundles.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for JWTBundlesResponse { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for JWTBundlesResponse { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct ValidateJWTSVIDRequest { + // message fields + pub audience: ::std::string::String, + pub svid: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a ValidateJWTSVIDRequest { + fn default() -> &'a ValidateJWTSVIDRequest { + ::default_instance() + } +} + +impl ValidateJWTSVIDRequest { + pub fn new() -> ValidateJWTSVIDRequest { + ::std::default::Default::default() + } + + // string audience = 1; + + + pub fn get_audience(&self) -> &str { + &self.audience + } + pub fn clear_audience(&mut self) { + self.audience.clear(); + } + + // Param is passed by value, moved + pub fn set_audience(&mut self, v: ::std::string::String) { + self.audience = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_audience(&mut self) -> &mut ::std::string::String { + &mut self.audience + } + + // Take field + pub fn take_audience(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.audience, ::std::string::String::new()) + } + + // string svid = 2; + + + pub fn get_svid(&self) -> &str { + &self.svid + } + pub fn clear_svid(&mut self) { + self.svid.clear(); + } + + // Param is passed by value, moved + pub fn set_svid(&mut self, v: ::std::string::String) { + self.svid = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_svid(&mut self) -> &mut ::std::string::String { + &mut self.svid + } + + // Take field + pub fn take_svid(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.svid, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for ValidateJWTSVIDRequest { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.audience)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.svid)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.audience.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.audience); + } + if !self.svid.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.svid); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.audience.is_empty() { + os.write_string(1, &self.audience)?; + } + if !self.svid.is_empty() { + os.write_string(2, &self.svid)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> ValidateJWTSVIDRequest { + ValidateJWTSVIDRequest::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "audience", + |m: &ValidateJWTSVIDRequest| { &m.audience }, + |m: &mut ValidateJWTSVIDRequest| { &mut m.audience }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "svid", + |m: &ValidateJWTSVIDRequest| { &m.svid }, + |m: &mut ValidateJWTSVIDRequest| { &mut m.svid }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "ValidateJWTSVIDRequest", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static ValidateJWTSVIDRequest { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(ValidateJWTSVIDRequest::new) + } +} + +impl ::protobuf::Clear for ValidateJWTSVIDRequest { + fn clear(&mut self) { + self.audience.clear(); + self.svid.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for ValidateJWTSVIDRequest { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for ValidateJWTSVIDRequest { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct ValidateJWTSVIDResponse { + // message fields + pub spiffe_id: ::std::string::String, + pub claims: ::protobuf::SingularPtrField<::protobuf::well_known_types::Struct>, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a ValidateJWTSVIDResponse { + fn default() -> &'a ValidateJWTSVIDResponse { + ::default_instance() + } +} + +impl ValidateJWTSVIDResponse { + pub fn new() -> ValidateJWTSVIDResponse { + ::std::default::Default::default() + } + + // string spiffe_id = 1; + + + pub fn get_spiffe_id(&self) -> &str { + &self.spiffe_id + } + pub fn clear_spiffe_id(&mut self) { + self.spiffe_id.clear(); + } + + // Param is passed by value, moved + pub fn set_spiffe_id(&mut self, v: ::std::string::String) { + self.spiffe_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_spiffe_id(&mut self) -> &mut ::std::string::String { + &mut self.spiffe_id + } + + // Take field + pub fn take_spiffe_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.spiffe_id, ::std::string::String::new()) + } + + // .google.protobuf.Struct claims = 2; + + + pub fn get_claims(&self) -> &::protobuf::well_known_types::Struct { + self.claims.as_ref().unwrap_or_else(|| <::protobuf::well_known_types::Struct as ::protobuf::Message>::default_instance()) + } + pub fn clear_claims(&mut self) { + self.claims.clear(); + } + + pub fn has_claims(&self) -> bool { + self.claims.is_some() + } + + // Param is passed by value, moved + pub fn set_claims(&mut self, v: ::protobuf::well_known_types::Struct) { + self.claims = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_claims(&mut self) -> &mut ::protobuf::well_known_types::Struct { + if self.claims.is_none() { + self.claims.set_default(); + } + self.claims.as_mut().unwrap() + } + + // Take field + pub fn take_claims(&mut self) -> ::protobuf::well_known_types::Struct { + self.claims.take().unwrap_or_else(|| ::protobuf::well_known_types::Struct::new()) + } +} + +impl ::protobuf::Message for ValidateJWTSVIDResponse { + fn is_initialized(&self) -> bool { + for v in &self.claims { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.spiffe_id)?; + }, + 2 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.claims)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.spiffe_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.spiffe_id); + } + if let Some(ref v) = self.claims.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.spiffe_id.is_empty() { + os.write_string(1, &self.spiffe_id)?; + } + if let Some(ref v) = self.claims.as_ref() { + os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> ValidateJWTSVIDResponse { + ValidateJWTSVIDResponse::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "spiffe_id", + |m: &ValidateJWTSVIDResponse| { &m.spiffe_id }, + |m: &mut ValidateJWTSVIDResponse| { &mut m.spiffe_id }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<::protobuf::well_known_types::Struct>>( + "claims", + |m: &ValidateJWTSVIDResponse| { &m.claims }, + |m: &mut ValidateJWTSVIDResponse| { &mut m.claims }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "ValidateJWTSVIDResponse", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static ValidateJWTSVIDResponse { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(ValidateJWTSVIDResponse::new) + } +} + +impl ::protobuf::Clear for ValidateJWTSVIDResponse { + fn clear(&mut self) { + self.spiffe_id.clear(); + self.claims.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for ValidateJWTSVIDResponse { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for ValidateJWTSVIDResponse { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +static file_descriptor_proto_data: &'static [u8] = b"\ + \n\x1fsrc/workload/workload_api.proto\x1a\x1cgoogle/protobuf/struct.prot\ + o\"\x11\n\x0fX509SVIDRequest\"\xe0\x01\n\x10X509SVIDResponse\x12\x1f\n\ + \x05svids\x18\x01\x20\x03(\x0b2\t.X509SVIDR\x05svids\x12\x10\n\x03crl\ + \x18\x02\x20\x03(\x0cR\x03crl\x12T\n\x11federated_bundles\x18\x03\x20\ + \x03(\x0b2'.X509SVIDResponse.FederatedBundlesEntryR\x10federatedBundles\ + \x1aC\n\x15FederatedBundlesEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\ + \x03key\x12\x14\n\x05value\x18\x02\x20\x01(\x0cR\x05value:\x028\x01\"\ + \x80\x01\n\x08X509SVID\x12\x1b\n\tspiffe_id\x18\x01\x20\x01(\tR\x08spiff\ + eId\x12\x1b\n\tx509_svid\x18\x02\x20\x01(\x0cR\x08x509Svid\x12\"\n\rx509\ + _svid_key\x18\x03\x20\x01(\x0cR\x0bx509SvidKey\x12\x16\n\x06bundle\x18\ + \x04\x20\x01(\x0cR\x06bundle\":\n\x07JWTSVID\x12\x1b\n\tspiffe_id\x18\ + \x01\x20\x01(\tR\x08spiffeId\x12\x12\n\x04svid\x18\x02\x20\x01(\tR\x04sv\ + id\"I\n\x0eJWTSVIDRequest\x12\x1a\n\x08audience\x18\x01\x20\x03(\tR\x08a\ + udience\x12\x1b\n\tspiffe_id\x18\x02\x20\x01(\tR\x08spiffeId\"1\n\x0fJWT\ + SVIDResponse\x12\x1e\n\x05svids\x18\x01\x20\x03(\x0b2\x08.JWTSVIDR\x05sv\ + ids\"\x13\n\x11JWTBundlesRequest\"\x8c\x01\n\x12JWTBundlesResponse\x12:\ + \n\x07bundles\x18\x01\x20\x03(\x0b2\x20.JWTBundlesResponse.BundlesEntryR\ + \x07bundles\x1a:\n\x0cBundlesEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\ + \x03key\x12\x14\n\x05value\x18\x02\x20\x01(\x0cR\x05value:\x028\x01\"H\n\ + \x16ValidateJWTSVIDRequest\x12\x1a\n\x08audience\x18\x01\x20\x01(\tR\x08\ + audience\x12\x12\n\x04svid\x18\x02\x20\x01(\tR\x04svid\"g\n\x17ValidateJ\ + WTSVIDResponse\x12\x1b\n\tspiffe_id\x18\x01\x20\x01(\tR\x08spiffeId\x12/\ + \n\x06claims\x18\x02\x20\x01(\x0b2\x17.google.protobuf.StructR\x06claims\ + 2\x82\x02\n\x11SpiffeWorkloadAPI\x121\n\x0cFetchJWTSVID\x12\x0f.JWTSVIDR\ + equest\x1a\x10.JWTSVIDResponse\x12<\n\x0fFetchJWTBundles\x12\x12.JWTBund\ + lesRequest\x1a\x13.JWTBundlesResponse0\x01\x12D\n\x0fValidateJWTSVID\x12\ + \x17.ValidateJWTSVIDRequest\x1a\x18.ValidateJWTSVIDResponse\x126\n\rFetc\ + hX509SVID\x12\x10.X509SVIDRequest\x1a\x11.X509SVIDResponse0\x01J\xb6\x17\ + \n\x06\x12\x04\x02\0]\x01\nk\n\x01\x0c\x12\x03\x02\0\x122a\x20Taken\x20f\ + rom\x20https://github.com/spiffe/go-spiffe/blob/master/proto/spiffe/work\ + load/workload.proto\n\n\t\n\x02\x03\0\x12\x03\x04\0&\n\t\n\x02\x04\0\x12\ + \x03\x06\0\x1c\n\n\n\x03\x04\0\x01\x12\x03\x06\x08\x17\n\xd3\x01\n\x02\ + \x04\x01\x12\x04\x0b\0\x18\x01\x1a\xc6\x01\x20The\x20X509SVIDResponse\ + \x20message\x20carries\x20a\x20set\x20of\x20X.509\x20SVIDs\x20and\x20the\ + ir\n\x20associated\x20information.\x20It\x20also\x20carries\x20a\x20set\ + \x20of\x20global\x20CRLs,\x20and\x20a\n\x20TTL\x20to\x20inform\x20the\ + \x20workload\x20when\x20it\x20should\x20check\x20back\x20next.\n\n\n\n\ + \x03\x04\x01\x01\x12\x03\x0b\x08\x18\n\x9a\x01\n\x04\x04\x01\x02\0\x12\ + \x03\x0f\x04\x20\x1a\x8c\x01\x20A\x20list\x20of\x20X509SVID\x20messages,\ + \x20each\x20of\x20which\x20includes\x20a\x20single\n\x20SPIFFE\x20Verifi\ + able\x20Identity\x20Document,\x20along\x20with\x20its\x20private\x20key\ + \n\x20and\x20bundle.\n\n\x0c\n\x05\x04\x01\x02\0\x04\x12\x03\x0f\x04\x0c\ + \n\x0c\n\x05\x04\x01\x02\0\x06\x12\x03\x0f\r\x15\n\x0c\n\x05\x04\x01\x02\ + \0\x01\x12\x03\x0f\x16\x1b\n\x0c\n\x05\x04\x01\x02\0\x03\x12\x03\x0f\x1e\ + \x1f\n\x20\n\x04\x04\x01\x02\x01\x12\x03\x12\x04\x1b\x1a\x13\x20ASN.1\ + \x20DER\x20encoded\n\n\x0c\n\x05\x04\x01\x02\x01\x04\x12\x03\x12\x04\x0c\ + \n\x0c\n\x05\x04\x01\x02\x01\x05\x12\x03\x12\r\x12\n\x0c\n\x05\x04\x01\ + \x02\x01\x01\x12\x03\x12\x13\x16\n\x0c\n\x05\x04\x01\x02\x01\x03\x12\x03\ + \x12\x19\x1a\n\xb8\x01\n\x04\x04\x01\x02\x02\x12\x03\x17\x04-\x1a\xaa\ + \x01\x20CA\x20certificate\x20bundles\x20belonging\x20to\x20foreign\x20Tr\ + ust\x20Domains\x20that\x20the\n\x20workload\x20should\x20trust,\x20keyed\ + \x20by\x20the\x20SPIFFE\x20ID\x20of\x20the\x20foreign\n\x20domain.\x20Bu\ + ndles\x20are\x20ASN.1\x20DER\x20encoded.\n\n\x0c\n\x05\x04\x01\x02\x02\ + \x06\x12\x03\x17\x04\x16\n\x0c\n\x05\x04\x01\x02\x02\x01\x12\x03\x17\x17\ + (\n\x0c\n\x05\x04\x01\x02\x02\x03\x12\x03\x17+,\no\n\x02\x04\x02\x12\x04\ + \x1c\0*\x01\x1ac\x20The\x20X509SVID\x20message\x20carries\x20a\x20single\ + \x20SVID\x20and\x20all\x20associated\n\x20information,\x20including\x20C\ + A\x20bundles.\n\n\n\n\x03\x04\x02\x01\x12\x03\x1c\x08\x10\n6\n\x04\x04\ + \x02\x02\0\x12\x03\x1e\x04\x19\x1a)\x20The\x20SPIFFE\x20ID\x20of\x20the\ + \x20SVID\x20in\x20this\x20entry\n\n\x0c\n\x05\x04\x02\x02\0\x05\x12\x03\ + \x1e\x04\n\n\x0c\n\x05\x04\x02\x02\0\x01\x12\x03\x1e\x0b\x14\n\x0c\n\x05\ + \x04\x02\x02\0\x03\x12\x03\x1e\x17\x18\n\x86\x01\n\x04\x04\x02\x02\x01\ + \x12\x03\"\x04\x18\x1ay\x20ASN.1\x20DER\x20encoded\x20certificate\x20cha\ + in.\x20MAY\x20include\x20intermediates,\n\x20the\x20leaf\x20certificate\ + \x20(or\x20SVID\x20itself)\x20MUST\x20come\x20first.\n\n\x0c\n\x05\x04\ + \x02\x02\x01\x05\x12\x03\"\x04\t\n\x0c\n\x05\x04\x02\x02\x01\x01\x12\x03\ + \"\n\x13\n\x0c\n\x05\x04\x02\x02\x01\x03\x12\x03\"\x16\x17\nI\n\x04\x04\ + \x02\x02\x02\x12\x03%\x04\x1c\x1a<\x20ASN.1\x20DER\x20encoded\x20PKCS#8\ + \x20private\x20key.\x20MUST\x20be\x20unencrypted.\n\n\x0c\n\x05\x04\x02\ + \x02\x02\x05\x12\x03%\x04\t\n\x0c\n\x05\x04\x02\x02\x02\x01\x12\x03%\n\ + \x17\n\x0c\n\x05\x04\x02\x02\x02\x03\x12\x03%\x1a\x1b\nO\n\x04\x04\x02\ + \x02\x03\x12\x03)\x04\x15\x1aB\x20CA\x20certificates\x20belonging\x20to\ + \x20the\x20Trust\x20Domain\n\x20ASN.1\x20DER\x20encoded\n\n\x0c\n\x05\ + \x04\x02\x02\x03\x05\x12\x03)\x04\t\n\x0c\n\x05\x04\x02\x02\x03\x01\x12\ + \x03)\n\x10\n\x0c\n\x05\x04\x02\x02\x03\x03\x12\x03)\x13\x14\n\n\n\x02\ + \x04\x03\x12\x04,\01\x01\n\n\n\x03\x04\x03\x01\x12\x03,\x08\x0f\n\x0b\n\ + \x04\x04\x03\x02\0\x12\x03-\x04\x19\n\x0c\n\x05\x04\x03\x02\0\x05\x12\ + \x03-\x04\n\n\x0c\n\x05\x04\x03\x02\0\x01\x12\x03-\x0b\x14\n\x0c\n\x05\ + \x04\x03\x02\0\x03\x12\x03-\x17\x18\n6\n\x04\x04\x03\x02\x01\x12\x030\ + \x04\x14\x1a)\x20Encoded\x20using\x20JWS\x20Compact\x20Serialization\n\n\ + \x0c\n\x05\x04\x03\x02\x01\x05\x12\x030\x04\n\n\x0c\n\x05\x04\x03\x02\ + \x01\x01\x12\x030\x0b\x0f\n\x0c\n\x05\x04\x03\x02\x01\x03\x12\x030\x12\ + \x13\n\n\n\x02\x04\x04\x12\x043\09\x01\n\n\n\x03\x04\x04\x01\x12\x033\ + \x08\x16\n\x0b\n\x04\x04\x04\x02\0\x12\x034\x04!\n\x0c\n\x05\x04\x04\x02\ + \0\x04\x12\x034\x04\x0c\n\x0c\n\x05\x04\x04\x02\0\x05\x12\x034\r\x13\n\ + \x0c\n\x05\x04\x04\x02\0\x01\x12\x034\x14\x1c\n\x0c\n\x05\x04\x04\x02\0\ + \x03\x12\x034\x1f\x20\nY\n\x04\x04\x04\x02\x01\x12\x038\x04\x19\x1aL\x20\ + SPIFFE\x20ID\x20of\x20the\x20JWT\x20being\x20requested\n\x20If\x20not\ + \x20set,\x20all\x20IDs\x20will\x20be\x20returned\n\n\x0c\n\x05\x04\x04\ + \x02\x01\x05\x12\x038\x04\n\n\x0c\n\x05\x04\x04\x02\x01\x01\x12\x038\x0b\ + \x14\n\x0c\n\x05\x04\x04\x02\x01\x03\x12\x038\x17\x18\n\n\n\x02\x04\x05\ + \x12\x04;\0=\x01\n\n\n\x03\x04\x05\x01\x12\x03;\x08\x17\n\x0b\n\x04\x04\ + \x05\x02\0\x12\x03<\x04\x1f\n\x0c\n\x05\x04\x05\x02\0\x04\x12\x03<\x04\ + \x0c\n\x0c\n\x05\x04\x05\x02\0\x06\x12\x03<\r\x14\n\x0c\n\x05\x04\x05\ + \x02\0\x01\x12\x03<\x15\x1a\n\x0c\n\x05\x04\x05\x02\0\x03\x12\x03<\x1d\ + \x1e\n\t\n\x02\x04\x06\x12\x03?\0\x1d\n\n\n\x03\x04\x06\x01\x12\x03?\x08\ + \x19\n\n\n\x02\x04\x07\x12\x04A\0D\x01\n\n\n\x03\x04\x07\x01\x12\x03A\ + \x08\x1a\n2\n\x04\x04\x07\x02\0\x12\x03C\x04#\x1a%\x20JWK\x20sets,\x20ke\ + yed\x20by\x20trust\x20domain\x20URI\n\n\x0c\n\x05\x04\x07\x02\0\x06\x12\ + \x03C\x04\x16\n\x0c\n\x05\x04\x07\x02\0\x01\x12\x03C\x17\x1e\n\x0c\n\x05\ + \x04\x07\x02\0\x03\x12\x03C!\"\n\n\n\x02\x04\x08\x12\x04F\0K\x01\n\n\n\ + \x03\x04\x08\x01\x12\x03F\x08\x1e\n\x0b\n\x04\x04\x08\x02\0\x12\x03G\x04\ + \x18\n\x0c\n\x05\x04\x08\x02\0\x05\x12\x03G\x04\n\n\x0c\n\x05\x04\x08\ + \x02\0\x01\x12\x03G\x0b\x13\n\x0c\n\x05\x04\x08\x02\0\x03\x12\x03G\x16\ + \x17\n6\n\x04\x04\x08\x02\x01\x12\x03J\x04\x14\x1a)\x20Encoded\x20using\ + \x20JWS\x20Compact\x20Serialization\n\n\x0c\n\x05\x04\x08\x02\x01\x05\ + \x12\x03J\x04\n\n\x0c\n\x05\x04\x08\x02\x01\x01\x12\x03J\x0b\x0f\n\x0c\n\ + \x05\x04\x08\x02\x01\x03\x12\x03J\x12\x13\n\n\n\x02\x04\t\x12\x04M\0P\ + \x01\n\n\n\x03\x04\t\x01\x12\x03M\x08\x1f\n\x0b\n\x04\x04\t\x02\0\x12\ + \x03N\x04\x19\n\x0c\n\x05\x04\t\x02\0\x05\x12\x03N\x04\n\n\x0c\n\x05\x04\ + \t\x02\0\x01\x12\x03N\x0b\x14\n\x0c\n\x05\x04\t\x02\0\x03\x12\x03N\x17\ + \x18\n\x0b\n\x04\x04\t\x02\x01\x12\x03O\x04&\n\x0c\n\x05\x04\t\x02\x01\ + \x06\x12\x03O\x04\x1a\n\x0c\n\x05\x04\t\x02\x01\x01\x12\x03O\x1b!\n\x0c\ + \n\x05\x04\t\x02\x01\x03\x12\x03O$%\n\n\n\x02\x06\0\x12\x04R\0]\x01\n\n\ + \n\x03\x06\0\x01\x12\x03R\x08\x19\n\x1f\n\x04\x06\0\x02\0\x12\x03T\x04?\ + \x1a\x12\x20JWT-SVID\x20Profile\n\n\x0c\n\x05\x06\0\x02\0\x01\x12\x03T\ + \x08\x14\n\x0c\n\x05\x06\0\x02\0\x02\x12\x03T\x15#\n\x0c\n\x05\x06\0\x02\ + \0\x03\x12\x03T.=\n\x0b\n\x04\x06\0\x02\x01\x12\x03U\x04O\n\x0c\n\x05\ + \x06\0\x02\x01\x01\x12\x03U\x08\x17\n\x0c\n\x05\x06\0\x02\x01\x02\x12\ + \x03U\x18)\n\x0c\n\x05\x06\0\x02\x01\x06\x12\x03U4:\n\x0c\n\x05\x06\0\ + \x02\x01\x03\x12\x03U;M\n\x0b\n\x04\x06\0\x02\x02\x12\x03V\x04R\n\x0c\n\ + \x05\x06\0\x02\x02\x01\x12\x03V\x08\x17\n\x0c\n\x05\x06\0\x02\x02\x02\ + \x12\x03V\x18.\n\x0c\n\x05\x06\0\x02\x02\x03\x12\x03V9P\n\xd9\x01\n\x04\ + \x06\0\x02\x03\x12\x03\\\x04I\x1a\xcb\x01\x20X.509-SVID\x20Profile\n\x20\ + Fetch\x20all\x20SPIFFE\x20identities\x20the\x20workload\x20is\x20entitle\ + d\x20to,\x20as\n\x20well\x20as\x20related\x20information\x20like\x20trus\ + t\x20bundles\x20and\x20CRLs.\x20As\n\x20this\x20information\x20changes,\ + \x20subsequent\x20messages\x20will\x20be\x20sent.\n\n\x0c\n\x05\x06\0\ + \x02\x03\x01\x12\x03\\\x08\x15\n\x0c\n\x05\x06\0\x02\x03\x02\x12\x03\\\ + \x16%\n\x0c\n\x05\x06\0\x02\x03\x06\x12\x03\\06\n\x0c\n\x05\x06\0\x02\ + \x03\x03\x12\x03\\7Gb\x06proto3\ +"; + +static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; + +fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto { + ::protobuf::parse_from_bytes(file_descriptor_proto_data).unwrap() +} + +pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { + file_descriptor_proto_lazy.get(|| { + parse_descriptor_proto() + }) } diff --git a/spiffe/src/workload/workload_api_grpc.rs b/spiffe/src/workload/workload_api_grpc.rs index b7a53c2..7a46f17 100644 --- a/spiffe/src/workload/workload_api_grpc.rs +++ b/spiffe/src/workload/workload_api_grpc.rs @@ -3,7 +3,7 @@ // https://github.com/Manishearth/rust-clippy/issues/702 #![allow(unknown_lints)] -#![allow(clippy)] +#![allow(clippy::all)] #![cfg_attr(rustfmt, rustfmt_skip)] @@ -18,6 +18,27 @@ #![allow(unused_imports)] #![allow(unused_results)] +const METHOD_SPIFFE_WORKLOAD_API_FETCH_JWTSVID: ::grpcio::Method = ::grpcio::Method { + ty: ::grpcio::MethodType::Unary, + name: "/SpiffeWorkloadAPI/FetchJWTSVID", + req_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, + resp_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, +}; + +const METHOD_SPIFFE_WORKLOAD_API_FETCH_JWT_BUNDLES: ::grpcio::Method = ::grpcio::Method { + ty: ::grpcio::MethodType::ServerStreaming, + name: "/SpiffeWorkloadAPI/FetchJWTBundles", + req_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, + resp_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, +}; + +const METHOD_SPIFFE_WORKLOAD_API_VALIDATE_JWTSVID: ::grpcio::Method = ::grpcio::Method { + ty: ::grpcio::MethodType::Unary, + name: "/SpiffeWorkloadAPI/ValidateJWTSVID", + req_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, + resp_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, +}; + const METHOD_SPIFFE_WORKLOAD_API_FETCH_X509_SVID: ::grpcio::Method = ::grpcio::Method { ty: ::grpcio::MethodType::ServerStreaming, name: "/SpiffeWorkloadAPI/FetchX509SVID", @@ -25,6 +46,7 @@ const METHOD_SPIFFE_WORKLOAD_API_FETCH_X509_SVID: ::grpcio::Method ::grpcio::Result { + self.client.unary_call(&METHOD_SPIFFE_WORKLOAD_API_FETCH_JWTSVID, req, opt) + } + + pub fn fetch_jwtsvid(&self, req: &super::workload_api::JWTSVIDRequest) -> ::grpcio::Result { + self.fetch_jwtsvid_opt(req, ::grpcio::CallOption::default()) + } + + pub fn fetch_jwtsvid_async_opt(&self, req: &super::workload_api::JWTSVIDRequest, opt: ::grpcio::CallOption) -> ::grpcio::Result<::grpcio::ClientUnaryReceiver> { + self.client.unary_call_async(&METHOD_SPIFFE_WORKLOAD_API_FETCH_JWTSVID, req, opt) + } + + pub fn fetch_jwtsvid_async(&self, req: &super::workload_api::JWTSVIDRequest) -> ::grpcio::Result<::grpcio::ClientUnaryReceiver> { + self.fetch_jwtsvid_async_opt(req, ::grpcio::CallOption::default()) + } + + pub fn fetch_jwt_bundles_opt(&self, req: &super::workload_api::JWTBundlesRequest, opt: ::grpcio::CallOption) -> ::grpcio::Result<::grpcio::ClientSStreamReceiver> { + self.client.server_streaming(&METHOD_SPIFFE_WORKLOAD_API_FETCH_JWT_BUNDLES, req, opt) + } + + pub fn fetch_jwt_bundles(&self, req: &super::workload_api::JWTBundlesRequest) -> ::grpcio::Result<::grpcio::ClientSStreamReceiver> { + self.fetch_jwt_bundles_opt(req, ::grpcio::CallOption::default()) + } + + pub fn validate_jwtsvid_opt(&self, req: &super::workload_api::ValidateJWTSVIDRequest, opt: ::grpcio::CallOption) -> ::grpcio::Result { + self.client.unary_call(&METHOD_SPIFFE_WORKLOAD_API_VALIDATE_JWTSVID, req, opt) + } + + pub fn validate_jwtsvid(&self, req: &super::workload_api::ValidateJWTSVIDRequest) -> ::grpcio::Result { + self.validate_jwtsvid_opt(req, ::grpcio::CallOption::default()) + } + + pub fn validate_jwtsvid_async_opt(&self, req: &super::workload_api::ValidateJWTSVIDRequest, opt: ::grpcio::CallOption) -> ::grpcio::Result<::grpcio::ClientUnaryReceiver> { + self.client.unary_call_async(&METHOD_SPIFFE_WORKLOAD_API_VALIDATE_JWTSVID, req, opt) + } + + pub fn validate_jwtsvid_async(&self, req: &super::workload_api::ValidateJWTSVIDRequest) -> ::grpcio::Result<::grpcio::ClientUnaryReceiver> { + self.validate_jwtsvid_async_opt(req, ::grpcio::CallOption::default()) + } + pub fn fetch_x509_svid_opt(&self, req: &super::workload_api::X509SVIDRequest, opt: ::grpcio::CallOption) -> ::grpcio::Result<::grpcio::ClientSStreamReceiver> { self.client.server_streaming(&METHOD_SPIFFE_WORKLOAD_API_FETCH_X509_SVID, req, opt) } @@ -43,18 +105,33 @@ impl SpiffeWorkloadApiClient { pub fn fetch_x509_svid(&self, req: &super::workload_api::X509SVIDRequest) -> ::grpcio::Result<::grpcio::ClientSStreamReceiver> { self.fetch_x509_svid_opt(req, ::grpcio::CallOption::default()) } - pub fn spawn(&self, f: F) where F: ::futures::Future + Send + 'static { + pub fn spawn(&self, f: F) where F: ::futures::Future + Send + 'static { self.client.spawn(f) } } pub trait SpiffeWorkloadApi { - fn fetch_x509_svid(&self, ctx: ::grpcio::RpcContext, req: super::workload_api::X509SVIDRequest, sink: ::grpcio::ServerStreamingSink); + fn fetch_jwtsvid(&mut self, ctx: ::grpcio::RpcContext, req: super::workload_api::JWTSVIDRequest, sink: ::grpcio::UnarySink); + fn fetch_jwt_bundles(&mut self, ctx: ::grpcio::RpcContext, req: super::workload_api::JWTBundlesRequest, sink: ::grpcio::ServerStreamingSink); + fn validate_jwtsvid(&mut self, ctx: ::grpcio::RpcContext, req: super::workload_api::ValidateJWTSVIDRequest, sink: ::grpcio::UnarySink); + fn fetch_x509_svid(&mut self, ctx: ::grpcio::RpcContext, req: super::workload_api::X509SVIDRequest, sink: ::grpcio::ServerStreamingSink); } pub fn create_spiffe_workload_api(s: S) -> ::grpcio::Service { let mut builder = ::grpcio::ServiceBuilder::new(); - let instance = s.clone(); + let mut instance = s.clone(); + builder = builder.add_unary_handler(&METHOD_SPIFFE_WORKLOAD_API_FETCH_JWTSVID, move |ctx, req, resp| { + instance.fetch_jwtsvid(ctx, req, resp) + }); + let mut instance = s.clone(); + builder = builder.add_server_streaming_handler(&METHOD_SPIFFE_WORKLOAD_API_FETCH_JWT_BUNDLES, move |ctx, req, resp| { + instance.fetch_jwt_bundles(ctx, req, resp) + }); + let mut instance = s.clone(); + builder = builder.add_unary_handler(&METHOD_SPIFFE_WORKLOAD_API_VALIDATE_JWTSVID, move |ctx, req, resp| { + instance.validate_jwtsvid(ctx, req, resp) + }); + let mut instance = s; builder = builder.add_server_streaming_handler(&METHOD_SPIFFE_WORKLOAD_API_FETCH_X509_SVID, move |ctx, req, resp| { instance.fetch_x509_svid(ctx, req, resp) }); diff --git a/spiffe/src/workload/x509.rs b/spiffe/src/workload/x509.rs new file mode 100644 index 0000000..775f7ea --- /dev/null +++ b/spiffe/src/workload/x509.rs @@ -0,0 +1,120 @@ +use crate::svid::{x509::Bundle, x509::X509, SVID}; +use crate::workload::workload_api::{X509SVIDRequest, X509SVIDResponse}; +use crate::workload::workload_api_grpc::SpiffeWorkloadApiClient; +use crate::workload::INITIAL_CONNECTION_TIMEOUT; +use crate::workload::MAX_CLIENT_BACKOFF; +use crate::workload::{Error, ErrorKind, Result, ResultExt}; +use futures::executor::block_on; +use futures::StreamExt; +use grpcio::{ChannelBuilder, EnvBuilder}; +use std::collections::HashMap; +use std::sync::Arc; +use std::time::Duration; +use std::vec::Vec; + +type CRL = Vec; + +#[derive(Debug)] +pub struct X509Payload { + svids: Vec>, + federated_bundles: HashMap, + crl: Vec, +} + +pub type X509Response = X509SVIDResponse; + +impl X509Payload { + pub fn new(response: X509Response) -> Result { + let mut svids = Vec::>::with_capacity(response.svids.len()); + + for x in response.svids.into_iter() { + let svid = SVID::::from_der( + &x.x509_svid, + Some(x.bundle.to_vec()), + Some(x.x509_svid_key.to_vec()), + )?; + + svids.push(svid); + } + + Ok(X509Payload { + svids, + federated_bundles: response.federated_bundles, + crl: response.crl.into_vec(), + }) + } + + pub fn svids(&self) -> &Vec> { + &self.svids + } + + pub fn federated_bundles(&self) -> &HashMap { + &self.federated_bundles + } + + pub fn crl(&self) -> &Vec { + &self.crl + } +} + +pub type X509Stream = ::grpcio::ClientSStreamReceiver; + +pub struct X509Client { + client: SpiffeWorkloadApiClient, +} + +impl X509Client { + pub fn new(addr: &str, backoff: Option) -> X509Client { + let backoff = backoff.unwrap_or(*MAX_CLIENT_BACKOFF); + let env = Arc::new(EnvBuilder::new().build()); + let channel = ChannelBuilder::new(env) + .initial_reconnect_backoff(backoff) + .max_reconnect_backoff(backoff) + .connect(addr); + X509Client { + client: SpiffeWorkloadApiClient::new(channel), + } + } + + pub fn fetch(&self, timeout: Option) -> Result> { + let mut metadata = ::grpcio::MetadataBuilder::new(); + metadata + .add_str("workload.spiffe.io", "true") + .chain_err(|| ErrorKind::ClientConfigFailure)?; + + let options = ::grpcio::CallOption::default() + .timeout(timeout.unwrap_or(*INITIAL_CONNECTION_TIMEOUT)) + .headers(metadata.build()); + + let mut rx = self + .client + .fetch_x509_svid_opt(&X509SVIDRequest::new(), options) + .chain_err(|| ErrorKind::ClientConfigFailure)?; + + let item = block_on(rx.next()); + + match item { + Some(Ok(item)) => Ok(X509Payload::new(item)), + Some(Err(e)) => Err(Error::with_chain(e, ErrorKind::FetchFailure)), + None => Err(ErrorKind::FetchFailure.into()), + } + } + + pub fn stream(&self, timeout: Option) -> Result { + let mut metadata = ::grpcio::MetadataBuilder::new(); + metadata + .add_str("workload.spiffe.io", "true") + .chain_err(|| ErrorKind::ClientConfigFailure)?; + + let options = ::grpcio::CallOption::default() + .timeout(timeout.unwrap_or(*INITIAL_CONNECTION_TIMEOUT)) + .headers(metadata.build()); + + let rx = self + .client + .fetch_x509_svid_opt(&X509SVIDRequest::new(), options) + .chain_err(|| ErrorKind::ClientConfigFailure)?; + + Ok(rx) + } +} diff --git a/spiffe/tests/svid_test.rs b/spiffe/tests/svid_test.rs index f89f3bd..1341124 100644 --- a/spiffe/tests/svid_test.rs +++ b/spiffe/tests/svid_test.rs @@ -4,8 +4,8 @@ extern crate assert_matches; extern crate openssl; extern crate spiffe; -use spiffe::svid::{Error, ErrorKind}; -use spiffe::svid::{SVID, X509}; +use spiffe::svid::x509::{Error, ErrorKind, X509}; +use spiffe::svid::SVID; use std::path::Path; static GOOD_CERTIFICATE: &str = r#" diff --git a/spiffe/tests/workload_test.rs b/spiffe/tests/workload_test.rs index 441663e..513330d 100644 --- a/spiffe/tests/workload_test.rs +++ b/spiffe/tests/workload_test.rs @@ -1,11 +1,14 @@ extern crate futures; extern crate spiffe; -use spiffe::workload::*; +use spiffe::workload::jwt::JWTClient; +use spiffe::workload::x509::{X509Client, X509Payload}; +use spiffe::workload::{Error, ErrorKind}; use std::time::Duration; -use futures::Future; -use futures::Stream; +use futures::executor::block_on; +use futures::future; +use futures::StreamExt; #[macro_use] extern crate assert_matches; @@ -53,24 +56,38 @@ fn x509_fetch_once_fail_no_uri() { #[test] fn x509_stream_take_one() { let client = X509Client::new("unix:///tmp/agent.sock", None); - let stream = client.stream(Some(Duration::new(5, 0))).unwrap(); - let _item = match stream.take(1).collect().wait() { - Ok(mut items) => { - let val = items.pop().unwrap(); - X509Payload::new(val).unwrap() + let mut stream = client.stream(Some(Duration::new(5, 0))).unwrap(); + let item = block_on(stream.next()); + + match item { + Some(Ok(item)) => { + X509Payload::new(item).unwrap(); } - _ => panic!("Expected responses returned"), - }; + Some(Err(_)) => panic!("Expected responses returned"), + None => panic!("Expected responses returned"), + } } #[test] fn x509_stream_for_each() { let client = X509Client::new("unix:///tmp/agent.sock", None); let stream = client.stream(Some(Duration::new(60, 0))).unwrap(); - let _res = stream - .take(2) - .for_each(|val| { - X509Payload::new(val).unwrap(); - Ok(()) - }).wait(); + let _res = stream.take(2).for_each(|val| { + X509Payload::new(val.unwrap()).unwrap(); + future::ready(()) + }); +} + +#[test] +fn jwt_validate_svid() { + let client = JWTClient::new("unix:///tmp/agent.sock", None); + + let svid = String::from("eyJhbGciOiJFUzI1NiIsImtpZCI6Im04cXZmTXNDYWp2Wkhac3o1Y21qbkJIMlVvMjVDQ0ZYIiwidHlwIjoiSldUIn0.eyJhdWQiOlsicGFyc2VjIl0sImV4cCI6MTYwMjEwMTcxOSwiaWF0IjoxNjAyMTAxNDE5LCJzdWIiOiJzcGlmZmU6Ly9leGFtcGxlLm9yZy9teXNlcnZpY2UifQ.EPpsPJg48T616vZEoZqclR8HjRyTj8qTUCymf5yWYTFXI2goL9bLCZP8Im6heHE_4o7JhRGgpzXbjxmqzgsUyw"); + let audience = String::from("parsec"); + + let result = client + .validate(audience, svid, Some(Duration::new(5, 0))) + .unwrap(); + println!("{:?}", result.0); + println!("{:?}", result.1); }