summaryrefslogtreecommitdiffstats
path: root/vendor/pasetors/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/pasetors/src/lib.rs')
-rw-r--r--vendor/pasetors/src/lib.rs360
1 files changed, 360 insertions, 0 deletions
diff --git a/vendor/pasetors/src/lib.rs b/vendor/pasetors/src/lib.rs
new file mode 100644
index 0000000..eb29a71
--- /dev/null
+++ b/vendor/pasetors/src/lib.rs
@@ -0,0 +1,360 @@
+//! # Getting started
+//! This library has two ways of working with tokens. The first is the [`local`] and [`public`] module,
+//! which the below examples make use of. These use the latest version of PASETO for tokens,
+//! along with [`claims::Claims`], to enable a straightforward way of defining common claims.
+//! [`claims::ClaimsValidationRules`] lets you define validation rules, that are covered when using
+//! the [`local`] and [`public`] module. Using these modules means that validation of registered
+//! claims is handled automatically.
+//!
+//! If more control over the input is needed, and validation is handled manually, the [`version4`]/[`version2`]
+//! module provide a lower-level interface, where payloads are be provided as byte-slices.
+//!
+//! NOTE: [`claims`], [`local`] and [`public`] modules are __only available with default-features enabled__.
+//! ## Creating and verifying public tokens
+//! ```rust
+//! use pasetors::claims::{Claims, ClaimsValidationRules};
+//! use pasetors::keys::{Generate, AsymmetricKeyPair, AsymmetricSecretKey, AsymmetricPublicKey};
+//! use pasetors::{public, Public, version4::V4};
+//! use pasetors::token::{UntrustedToken, TrustedToken};
+//! use core::convert::TryFrom;
+//!
+//! // Setup the default claims, which include `iat` and `nbf` as the current time and `exp` of one hour.
+//! // Add a custom `data` claim as well.
+//! let mut claims = Claims::new()?;
+//! claims.add_additional("data", "A public, signed message")?;
+//!
+//! // Generate the keys and sign the claims.
+//! let kp = AsymmetricKeyPair::<V4>::generate()?;
+//! let pub_token = public::sign(&kp.secret, &claims, None, Some(b"implicit assertion"))?;
+//!
+//! // Decide how we want to validate the claims after verifying the token itself.
+//! // The default verifies the `nbf`, `iat` and `exp` claims. `nbf` and `iat` are always
+//! // expected to be present.
+//! // NOTE: Custom claims, defined through `add_additional()`, are not validated. This must be done
+//! // manually.
+//! let validation_rules = ClaimsValidationRules::new();
+//! let untrusted_token = UntrustedToken::<Public, V4>::try_from(&pub_token)?;
+//! let trusted_token = public::verify(&kp.public, &untrusted_token, &validation_rules, None, Some(b"implicit assertion"))?;
+//! assert_eq!(&claims, trusted_token.payload_claims().unwrap());
+//!
+//! let claims = trusted_token.payload_claims().unwrap();
+//!
+//! println!("{:?}", claims.get_claim("data"));
+//! println!("{:?}", claims.get_claim("iat"));
+//!
+//! # Ok::<(), pasetors::errors::Error>(())
+//! ```
+
+//! ## Creating and verifying local tokens
+//! ```rust
+//! use pasetors::claims::{Claims, ClaimsValidationRules};
+//! use pasetors::keys::{Generate, SymmetricKey};
+//! use pasetors::{local, Local, version4::V4};
+//! use pasetors::token::UntrustedToken;
+//! use core::convert::TryFrom;
+//!
+//! // Setup the default claims, which include `iat` and `nbf` as the current time and `exp` of one hour.
+//! // Add a custom `data` claim as well.
+//! let mut claims = Claims::new()?;
+//! claims.add_additional("data", "A secret, encrypted message")?;
+//!
+//! // Generate the key and encrypt the claims.
+//! let sk = SymmetricKey::<V4>::generate()?;
+//! let token = local::encrypt(&sk, &claims, None, Some(b"implicit assertion"))?;
+//!
+//! // Decide how we want to validate the claims after verifying the token itself.
+//! // The default verifies the `nbf`, `iat` and `exp` claims. `nbf` and `iat` are always
+//! // expected to be present.
+//! // NOTE: Custom claims, defined through `add_additional()`, are not validated. This must be done
+//! // manually.
+//! let validation_rules = ClaimsValidationRules::new();
+//! let untrusted_token = UntrustedToken::<Local, V4>::try_from(&token)?;
+//! let trusted_token = local::decrypt(&sk, &untrusted_token, &validation_rules, None, Some(b"implicit assertion"))?;
+//! assert_eq!(&claims, trusted_token.payload_claims().unwrap());
+//!
+//! let claims = trusted_token.payload_claims().unwrap();
+//!
+//! println!("{:?}", claims.get_claim("data"));
+//! println!("{:?}", claims.get_claim("iat"));
+//!
+//! # Ok::<(), pasetors::errors::Error>(())
+//! ```
+
+//! ## Additional claims and their validation
+//!
+//! ### Setting registered claims and how to validate them
+//! ```rust
+//! use pasetors::claims::{Claims, ClaimsValidationRules};
+//!
+//! // `iat`, `nbf` and `exp` have been set automatically, but could also be overridden.
+//! let mut claims = Claims::new()?;
+//! claims.issuer("paragonie.com")?;
+//! claims.subject("test")?;
+//! claims.audience("pie-hosted.com")?;
+//! claims.expiration("2039-01-01T00:00:00+00:00")?;
+//! claims.not_before("2038-04-01T00:00:00+00:00")?;
+//! claims.issued_at("2038-03-17T00:00:00+00:00")?;
+//! claims.token_identifier("87IFSGFgPNtQNNuw0AtuLttPYFfYwOkjhqdWcLoYQHvL")?;
+//!
+//! let mut validation_rules = ClaimsValidationRules::new();
+//! validation_rules.validate_issuer_with("paragonie.com");
+//! validation_rules.validate_subject_with("test");
+//! validation_rules.validate_audience_with("pie-hosted.com");
+//! validation_rules.validate_token_identifier_with("87IFSGFgPNtQNNuw0AtuLttPYFfYwOkjhqdWcLoYQHvL");
+//!
+//! // The token has been set to be issued in the future and not valid yet, so validation fails.
+//! assert!(validation_rules.validate_claims(&claims).is_err());
+//! # Ok::<(), pasetors::errors::Error>(())
+//! ```
+//! ### Non-expiring tokens
+//! ```rust
+//! use pasetors::claims::{Claims, ClaimsValidationRules};
+//!
+//! // Non-expiring tokens
+//! let mut claims = Claims::new()?;
+//! claims.add_additional("data", "A public, signed message")?;
+//! claims.non_expiring();
+//! // Now claims can be validated as non-expiring when we define the validation rule as:
+//! let mut validation_rules = ClaimsValidationRules::new();
+//! validation_rules.allow_non_expiring();
+//!
+//! # Ok::<(), pasetors::errors::Error>(())
+//! ```
+
+//! ## Footer with registered and custom claims
+//! ```rust
+//! use pasetors::paserk::{FormatAsPaserk, Id};
+//! use pasetors::claims::{Claims, ClaimsValidationRules};
+//! use pasetors::footer::Footer;
+//! use pasetors::keys::{Generate, AsymmetricKeyPair};
+//! use pasetors::{public, Public, version4::V4};
+//! use pasetors::token::UntrustedToken;
+//! use core::convert::TryFrom;
+//!
+//! // Generate the key used to later sign a token.
+//! let kp = AsymmetricKeyPair::<V4>::generate()?;
+//! // Serialize the public key to PASERK "pid".
+//! let mut pid = Id::from(&kp.public);
+//! // Add the "pid" to the "kid" claim of a footer.
+//! let mut footer = Footer::new();
+//! footer.key_id(&pid);
+//! footer.add_additional("custom_footer_claim", "custom_value")?;
+//!
+//! let mut claims = Claims::new()?;
+//! let pub_token = public::sign(&kp.secret, &claims, Some(&footer), Some(b"implicit assertion"))?;
+//!
+//! // If we receive a token that needs to be verified, we can still try to parse a Footer from it
+//! // as long one was used during creation, if we don't know it beforehand.
+//! let validation_rules = ClaimsValidationRules::new();
+//! let untrusted_token = UntrustedToken::<Public, V4>::try_from(&pub_token)?;
+//! let trusted_token = public::verify(&kp.public, &untrusted_token, &validation_rules, None, Some(b"implicit assertion"))?;
+//! let trusted_footer = Footer::try_from(&trusted_token)?;
+//!
+//! let mut kid = String::new();
+//! pid.fmt(&mut kid).unwrap();
+//! assert_eq!(trusted_footer.get_claim("kid").unwrap().as_str().unwrap(), kid);
+//!
+//! # Ok::<(), pasetors::errors::Error>(())
+//! ```
+
+//! ## PASERK serialization
+//! ```rust
+//! use pasetors::paserk::FormatAsPaserk;
+//! use pasetors::keys::{Generate, SymmetricKey};
+//! use pasetors::version4::V4;
+//! use core::convert::TryFrom;
+//!
+//! // Generate the key and serialize to and from PASERK.
+//! let sk = SymmetricKey::<V4>::generate()?;
+//! let mut paserk = String::new();
+//! sk.fmt(&mut paserk).unwrap();
+//! let sk = SymmetricKey::<V4>::try_from(paserk.as_str())?;
+//!
+//! # Ok::<(), pasetors::errors::Error>(())
+//! ```
+
+#![cfg_attr(not(feature = "std"), no_std)]
+#![forbid(unsafe_code)]
+#![deny(clippy::mem_forget)]
+#![warn(
+ missing_docs,
+ rust_2018_idioms,
+ trivial_casts,
+ unused_qualifications,
+ overflowing_literals
+)]
+#![doc(html_root_url = "https://docs.rs/pasetors/0.6.7")]
+#![cfg_attr(docsrs, feature(doc_cfg))]
+
+#[macro_use]
+extern crate alloc;
+
+mod pae;
+
+/// Errors for token operations.
+pub mod errors;
+
+mod common;
+
+#[cfg(feature = "std")]
+/// Claims for tokens and validation thereof.
+pub mod claims;
+
+#[cfg(feature = "std")]
+/// Footer for tokens.
+pub mod footer;
+
+/// Keys used for PASETO tokens.
+pub mod keys;
+
+#[cfg(feature = "paserk")]
+/// PASERK key-wrapping and serialization.
+pub mod paserk;
+
+#[cfg(feature = "v2")]
+/// PASETO version 2 tokens.
+pub mod version2;
+
+#[cfg(feature = "v3")]
+/// PASETO version 3 tokens.
+pub mod version3;
+
+#[cfg(feature = "v4")]
+/// PASETO version 4 tokens.
+pub mod version4;
+
+/// Types for handling tokens.
+pub mod token;
+
+#[cfg(feature = "serde")]
+/// Serialization and deserialization support for various types.
+mod serde;
+
+mod version;
+
+/// Public and local tokens.
+pub use token::{Local, Public};
+
+#[cfg_attr(docsrs, doc(cfg(all(feature = "std", feature = "v4"))))]
+#[cfg(all(feature = "std", feature = "v4"))]
+/// PASETO public tokens with [`version4`], using [`claims::Claims`].
+pub mod public {
+ use super::*;
+ use crate::claims::{Claims, ClaimsValidationRules};
+ use crate::errors::Error;
+ use crate::footer::Footer;
+ use crate::keys::{AsymmetricPublicKey, AsymmetricSecretKey};
+ use crate::token::{TrustedToken, UntrustedToken};
+ use crate::version4::V4;
+
+ /// Create a public token using the latest PASETO version (v4).
+ pub fn sign(
+ secret_key: &AsymmetricSecretKey<V4>,
+ message: &Claims,
+ footer: Option<&Footer>,
+ implicit_assert: Option<&[u8]>,
+ ) -> Result<String, Error> {
+ match footer {
+ Some(f) => crate::version4::PublicToken::sign(
+ secret_key,
+ message.to_string()?.as_bytes(),
+ Some(f.to_string()?.as_bytes()),
+ implicit_assert,
+ ),
+ None => crate::version4::PublicToken::sign(
+ secret_key,
+ message.to_string()?.as_bytes(),
+ None,
+ implicit_assert,
+ ),
+ }
+ }
+
+ /// Verify a public token using the latest PASETO version (v4). If verification passes,
+ /// validate the claims according to the `validation_rules`.
+ pub fn verify(
+ public_key: &AsymmetricPublicKey<V4>,
+ token: &UntrustedToken<Public, V4>,
+ validation_rules: &ClaimsValidationRules,
+ footer: Option<&Footer>,
+ implicit_assert: Option<&[u8]>,
+ ) -> Result<TrustedToken, Error> {
+ let mut trusted_token = match footer {
+ Some(f) => crate::version4::PublicToken::verify(
+ public_key,
+ token,
+ Some(f.to_string()?.as_bytes()),
+ implicit_assert,
+ )?,
+ None => crate::version4::PublicToken::verify(public_key, token, None, implicit_assert)?,
+ };
+
+ let claims = Claims::from_string(trusted_token.payload())?;
+ validation_rules.validate_claims(&claims)?;
+ trusted_token.set_payload_claims(claims);
+
+ Ok(trusted_token)
+ }
+}
+
+#[cfg_attr(docsrs, doc(cfg(all(feature = "std", feature = "v4"))))]
+#[cfg(all(feature = "std", feature = "v4"))]
+/// PASETO local tokens with [`version4`], using [`claims::Claims`].
+pub mod local {
+ use super::*;
+ use crate::claims::{Claims, ClaimsValidationRules};
+ use crate::errors::Error;
+ use crate::footer::Footer;
+ use crate::keys::SymmetricKey;
+ use crate::token::{TrustedToken, UntrustedToken};
+ use crate::version4::V4;
+
+ /// Create a local token using the latest PASETO version (v4).
+ pub fn encrypt(
+ secret_key: &SymmetricKey<V4>,
+ message: &Claims,
+ footer: Option<&Footer>,
+ implicit_assert: Option<&[u8]>,
+ ) -> Result<String, Error> {
+ match footer {
+ Some(f) => crate::version4::LocalToken::encrypt(
+ secret_key,
+ message.to_string()?.as_bytes(),
+ Some(f.to_string()?.as_bytes()),
+ implicit_assert,
+ ),
+ None => crate::version4::LocalToken::encrypt(
+ secret_key,
+ message.to_string()?.as_bytes(),
+ None,
+ implicit_assert,
+ ),
+ }
+ }
+
+ /// Verify a local token using the latest PASETO version (v4). If verification passes,
+ /// validate the claims according to the `validation_rules`.
+ pub fn decrypt(
+ secret_key: &SymmetricKey<V4>,
+ token: &UntrustedToken<Local, V4>,
+ validation_rules: &ClaimsValidationRules,
+ footer: Option<&Footer>,
+ implicit_assert: Option<&[u8]>,
+ ) -> Result<TrustedToken, Error> {
+ let mut trusted_token = match footer {
+ Some(f) => crate::version4::LocalToken::decrypt(
+ secret_key,
+ token,
+ Some(f.to_string()?.as_bytes()),
+ implicit_assert,
+ )?,
+ None => crate::version4::LocalToken::decrypt(secret_key, token, None, implicit_assert)?,
+ };
+
+ let claims = Claims::from_string(trusted_token.payload())?;
+ validation_rules.validate_claims(&claims)?;
+ trusted_token.set_payload_claims(claims);
+
+ Ok(trusted_token)
+ }
+}