diff --git a/src/jose.rs b/src/jose.rs index bbf97c5..cf99108 100644 --- a/src/jose.rs +++ b/src/jose.rs @@ -1,4 +1,5 @@ use std::fmt; +use std::time::Duration; use base64ct::{Base64Url, Base64UrlUnpadded, Encoding}; use elliptic_curve::sec1::{EncodedPoint, FromEncodedPoint, ModulusSize, ToEncodedPoint}; @@ -16,7 +17,7 @@ use zeroize::Zeroize; use crate::key_exchange::{create_enc_key, recover_enc_key}; use crate::util::{b64_to_bytes, b64_to_str}; -use crate::{EncryptionKey, Error, Result}; +use crate::{EncryptionKey, Error, Result, TangClient}; /// Representation of a tang advertisment response which is a JWS of available keys. /// @@ -486,7 +487,6 @@ struct TangParams { impl KeyMeta { /// Serialize this data to a JSON string - #[must_use] pub fn to_json(&self) -> String { serde_json::to_string(self).expect("serialization failure") } @@ -496,6 +496,16 @@ impl KeyMeta { serde_json::from_str(val).map_err(Into::into) } + /// Create a [`TangClient`] from the URL used to generate this key + pub fn client(&self, timeout: Option) -> TangClient { + TangClient::new(&self.clevis.tang.url, timeout) + } + + /// The URL that was used to generate this key + pub fn url(&self) -> &str { + &self.clevis.tang.url + } + pub(crate) fn recover_key( &self, server_key_exchange: impl FnOnce(&str, &Jwk) -> Result, diff --git a/src/lib.rs b/src/lib.rs index d1f29b6..d72a88c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,20 +4,20 @@ //! This is still under development, but works reasonibly well. //! //! ``` -//! # #[cfg(not(feature = "_backend"))] fn main() {} -//! # #[cfg(feature = "_backend")] //! # fn main() { +//! # #[cfg(feature = "_backend")] test(); +//! # } +//! # +//! # fn test() { //! use clevis::{KeyMeta, TangClient}; //! -//! /// 32-byte (256 bit) key +//! /// 32-byte (256 bit) key, such as for AES256-GCM //! const KEY_BYTES: usize = 32; //! //! /* key provisioning */ //! -//! let client = TangClient::new("localhost:11697", None); -//! //! // create a key suitible for encryption (i.e. has gone through a KDF) -//! let out = client +//! let out = TangClient::new("localhost:11697", None) //! .create_secure_key::() //! .expect("failed to generate key"); //! @@ -33,7 +33,8 @@ //! /* key recovery */ //! //! let new_meta = KeyMeta::from_json(&meta_str).expect("invalid metadata"); -//! let new_key = client +//! let new_key = new_meta +//! .client(None) //! .recover_secure_key::(&new_meta) //! .expect("failed to retrieve key"); //! @@ -44,6 +45,7 @@ #![warn(clippy::pedantic)] #![allow(clippy::missing_panics_doc)] #![allow(clippy::missing_errors_doc)] +#![allow(clippy::must_use_candidate)] mod error; mod jose; diff --git a/src/tang_interface.rs b/src/tang_interface.rs index 63176ee..829dcb6 100644 --- a/src/tang_interface.rs +++ b/src/tang_interface.rs @@ -6,7 +6,9 @@ use crate::{EncryptionKey, Result}; // const DEFAULT_URL: &str = "http://tang.local"; const DEFAULT_TIMEOUT: Duration = Duration::from_secs(120); -/// A tang server connection specification +/// A tang server connection specification. +/// +/// This does not hold an active connection, only connection parameters. #[derive(Clone, Debug)] pub struct TangClient { url: String, @@ -28,6 +30,11 @@ impl TangClient { } } + /// This client's connection URL + pub fn url(&self) -> &str { + &self.url + } + /// Locate derive keys from the server and provision an encryption key with specified lengh. pub fn create_secure_key(&self) -> Result> { let (keys, signing_thp) = self.fetch_keys(None)?;