### Create and verify public tokens Source: https://docs.rs/pasetors/0.7.8/src/pasetors/lib.rs.html Demonstrates signing claims with an asymmetric key pair and verifying the resulting token. ```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::::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::::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>(()) ``` -------------------------------- ### Get Type ID for ClaimsValidationRules Source: https://docs.rs/pasetors/0.7.8/pasetors/claims/struct.ClaimsValidationRules.html Gets the `TypeId` of the `ClaimsValidationRules` instance. ```rust fn type_id(&self) -> TypeId ``` -------------------------------- ### Get Token Payload Source: https://docs.rs/pasetors/0.7.8/pasetors/token/struct.TrustedToken.html Retrieves the payload used for this token. ```rust pub fn payload(&self) -> &str ``` -------------------------------- ### Create and Verify Local Tokens with Pasetors Source: https://docs.rs/pasetors/0.7.8/pasetors/index.html This snippet demonstrates how to create and verify local PASETO tokens. It covers setting up claims, generating a symmetric key, encrypting the token, and decrypting it with validation. Ensure default-features are enabled for access to the `local` module. ```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::::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::::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")); ``` -------------------------------- ### Get Token Header Source: https://docs.rs/pasetors/0.7.8/pasetors/token/struct.TrustedToken.html Retrieves the header used for this token. ```rust pub fn header(&self) -> &str ``` -------------------------------- ### PASETO v3 Implementation Details Source: https://docs.rs/pasetors/0.7.8/pasetors/version3/index.html Overview of the structs and requirements for using PASETO version 3 tokens. ```APIDOC ## PASETO v3 Module ### Description Implementation of the version 3 specification of PASETO. Requires the `v3` crate feature. ### Key Components - **V3**: The primary struct representing Version 3 of the PASETO spec. - **PublicToken**: Represents PASETO v3 public tokens. - **UncompressedPublicKey**: Represents an uncompressed public key for P384, encoded in big-endian using the Octet-String-to-Elliptic-Curve-Point algorithm (SEC 1). ### Implementation Notes - PASETO requires the use of compressed public keys; use `UncompressedPublicKey` or `AsymmetricPublicKey` conversions if necessary. - Uses deterministic nonces (RFC 6979). - Hedged signatures are not used. ``` -------------------------------- ### Create and verify local tokens Source: https://docs.rs/pasetors/0.7.8/src/pasetors/lib.rs.html Demonstrates encrypting claims with a symmetric key and decrypting the resulting token. ```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::::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::::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>(()) ``` -------------------------------- ### GET /footer/serialize Source: https://docs.rs/pasetors/0.7.8/src/pasetors/footer.rs.html Serializes the current Footer object into a JSON string representation. ```APIDOC ## GET /footer/serialize ### Description Converts the internal Footer state into a JSON-serialized string. ### Method GET ### Endpoint /footer/serialize ### Response #### Success Response (200) - **body** (string) - The JSON serialized representation of the footer. #### Error Response (500) - **error** (string) - Returns FooterParsing error if serialization fails. ``` -------------------------------- ### Get Output Type Source: https://docs.rs/pasetors/0.7.8/pasetors/token/struct.TrustedToken.html Specifies the output type for trait implementations, which should always be `Self`. ```rust type Output = T ``` -------------------------------- ### Serialize AsymmetricPublicKey with Serde Source: https://docs.rs/pasetors/0.7.8/src/pasetors/serde.rs.html Implement Serde's Serialize for AsymmetricPublicKey. This allows the public key to be serialized into a paserk string format. Requires the 'paserk' feature. ```rust impl serde::Serialize for AsymmetricPublicKey where AsymmetricPublicKey: FormatAsPaserk, { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer, { use serde::ser::Error; let mut paserk_string = String::new(); self.fmt(&mut paserk_string).map_err(S::Error::custom)?; serializer.serialize_str(&paserk_string) } } ``` -------------------------------- ### Get Token Footer Source: https://docs.rs/pasetors/0.7.8/pasetors/token/struct.TrustedToken.html Retrieves the footer used to create the token. This will be empty if `None` was used during creation. ```rust pub fn footer(&self) -> &[u8] ``` -------------------------------- ### Paseto V3 Sign and Verify Roundtrip Source: https://docs.rs/pasetors/0.7.8/src/pasetors/version3.rs.html Demonstrates signing a message and verifying the resulting token using Paseto V3 asymmetric keys. ```rust #[test] fn sign_verify_roundtrip() { // Values taken from 3-S-1 let raw_sk = hex::decode("20347609607477aca8fbfbc5e6218455f3199669792ef8b466faa87bdc67798144c848dd03661eed5ac62461340cea96").unwrap(); let raw_pk = hex::decode("02fbcb7c69ee1c60579be7a334134878d9c5c5bf35d552dab63c0140397ed14cef637d7720925c44699ea30e72874c72fb").unwrap(); let sk = AsymmetricSecretKey::::from(&raw_sk).unwrap(); let pk = AsymmetricPublicKey::::from(&raw_pk).unwrap(); let message = "this is a signed message"; let token = UntrustedToken::::try_from( &PublicToken::sign(&sk, message.as_bytes(), Some(b"footer"), Some(b"impl")).unwrap(), ) .unwrap(); assert!(PublicToken::verify(&pk, &token, Some(b"footer"), Some(b"impl")).is_ok()); } ``` -------------------------------- ### clone_to_uninit Source: https://docs.rs/pasetors/0.7.8/pasetors/keys/struct.SymmetricKey.html This is a nightly-only experimental API. Performs copy-assignment from `self` to `dest`. ```APIDOC ## unsafe fn clone_to_uninit(&self, dest: *mut u8) ### Description This is a nightly-only experimental API. Performs copy-assignment from `self` to `dest`. ### Method `unsafe fn` ### Endpoint N/A (Method within a trait implementation) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example None ### Response None ``` -------------------------------- ### Modify Public Token Signature Source: https://docs.rs/pasetors/0.7.8/src/pasetors/version2.rs.html Demonstrates modifying the signature part of a public token. This is a setup for testing signature validation failures. ```rust let mut split_public = VALID_PUBLIC_TOKEN.split('.').collect::>(); let mut bad_sig = decode_b64(split_public[2]).unwrap(); bad_sig.copy_within(0..32, 32); ``` -------------------------------- ### Sign and Verify Token with Footer Source: https://docs.rs/pasetors/0.7.8/src/pasetors/version3.rs.html Demonstrates signing a message with a footer and then verifying the token. The footer can be optionally provided during verification. ```rust const MESSAGE: &str = "{\"data\":\"this is a signed message\",\"exp\":\"2022-01-01T00:00:00+00:00\"}"; const FOOTER: &str = "{\"kid\":\"dYkISylxQeecEcHELfzF88UZrwbLolNiCdpzUHGw9Uqn\"}"; const VALID_PUBLIC_TOKEN: &str = "v3.public.eyJkYXRhIjoidGhpcyBpcyBhIHNpZ25lZCBtZXNzYWdlIiwiZXhwIjoiMjAyMi0wMS0wMVQwMDowMDowMCswMDowMCJ9ZWrbGZ6L0MDK72skosUaS0Dz7wJ_2bMcM6tOxFuCasO9GhwHrvvchqgXQNLQQyWzGC2wkr-VKII71AvkLpC8tJOrzJV1cap9NRwoFzbcXjzMZyxQ0wkshxZxx8ImmNWP.eyJraWQiOiJkWWtJU3lseFFlZWNFY0hFTGZ6Rjg4VVpyd2JMb2xOaUNkcHpVSEd3OVVxbiJ9"; #[test] fn test_untrusted_token_usage() { // Public let kp = AsymmetricKeyPair::::generate().unwrap(); let token = PublicToken::sign( &kp.secret, MESSAGE.as_bytes(), Some(FOOTER.as_bytes()), None, ) .unwrap(); let untrusted_token = UntrustedToken::::try_from(token.as_str()).unwrap(); assert!(PublicToken::verify( &kp.public, &untrusted_token, Some(untrusted_token.untrusted_footer()), None ) .is_ok()); } ``` -------------------------------- ### Get Implicit Assertion Source: https://docs.rs/pasetors/0.7.8/pasetors/token/struct.TrustedToken.html Retrieves the implicit assertion used to create the token. This will be empty if `None` was used during creation. If the token was created using `V2`, this will always be empty. ```rust pub fn implicit_assert(&self) -> &[u8] ``` -------------------------------- ### Get Validated Payload Claims Source: https://docs.rs/pasetors/0.7.8/pasetors/token/struct.TrustedToken.html Returns the optional and validated Claims parsed from the token's payload. Available on `crate feature`std` only. Returns `None` if no Claims have been parsed or validated, or `Some` if Claims have been parsed and validated. ```rust pub fn payload_claims(&self) -> Option<&Claims> ``` -------------------------------- ### Claims Struct and Initialization Source: https://docs.rs/pasetors/0.7.8/src/pasetors/claims.rs.html Documentation for the `Claims` struct and its constructors for creating new claim sets. ```APIDOC ## Claims Struct ### Description A collection of claims that are passed as payload for a PASETO token. ### Fields - **list_of** (HashMap) - A hash map storing the claims. ## `Claims::new()` ### Description Create a new `Claims` instance, setting: - `iat`, `nbf` to current UTC time - `exp` to one hour from the current time. ### Returns - `Result` - A new `Claims` instance or an error if time calculation overflows. ## `Claims::new_expires_in()` ### Description Create a new `Claims` instance expiring in a specified duration. - `iat`, `nbf` are set to current UTC time. - `exp` is set to `iat + duration`. ### Parameters #### Path Parameters - **duration** (*core::time::Duration*) - The duration until the token expires. ### Returns - `Result` - A new `Claims` instance or an error if time calculation overflows or duration conversion fails. ## `Claims::set_expires_in()` ### Description Set the `iat`, `nbf`, and `exp` claims for the `Claims` instance. - `iat` and `nbf` are set to the current UTC time. - `exp` is set to `iat + duration`. ### Parameters #### Path Parameters - **duration** (*core::time::Duration*) - The duration until the token expires. ### Returns - `Result<(), Error>` - Ok if successful, or an error if time calculation overflows or duration conversion fails. ## `Claims::non_expiring()` ### Description Removes the `exp` claim from the claims set, indicating that the token does not expire. ### Returns - `()` ``` -------------------------------- ### Create and Verify Public Tokens with Pasetors Source: https://docs.rs/pasetors/0.7.8/pasetors/index.html Use this snippet to create and verify public PASETO tokens. It demonstrates setting default and custom claims, generating asymmetric keys, signing tokens, and verifying them with specified validation rules. Ensure default-features are enabled for access to the `public` module. ```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::::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::::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")); ``` -------------------------------- ### AsymmetricPublicKey Implementations Source: https://docs.rs/pasetors/0.7.8/pasetors/keys/struct.AsymmetricPublicKey.html Provides methods for creating and accessing data from an AsymmetricPublicKey. ```APIDOC ## impl AsymmetricPublicKey ### pub fn from(bytes: &[u8]) -> Result Create a `AsymmetricPublicKey` from `bytes`. ### pub fn as_bytes(&self) -> &[u8] Return this as a byte-slice. ``` -------------------------------- ### Initialize ClaimsValidationRules Source: https://docs.rs/pasetors/0.7.8/src/pasetors/claims.rs.html Methods to create and configure validation rules. ```rust impl Default for ClaimsValidationRules { fn default() -> Self { Self::new() } } impl ClaimsValidationRules { /// Create a new `ClaimsValidationRules` instance, setting: /// - validation of `iat`, `nbf`, `exp` true pub fn new() -> Self { Self { validate_currently_valid: true, allow_non_expiring: false, validate_issuer: None, validate_subject: None, validate_audience: None, validate_token_identifier: None, } } /// Disables the validation of `iat` and `nbf`, from the `ValidAt` validation pattern. /// /// `iat` and `nbf` may still be present in the [`Claims`] payload, at validation time, but will not be parsed. /// This means, you can disable this validation without modifying the creation of your [`Claims`]. /// In case of using `allow_non_expiring()`, the validation expects no `exp` claim to be present within the payload. /// /// To disable the entire `ValidAt` pattern, specify also `allow_non_expiring()`. /// /// See [PASETO Validators](https://github.com/paseto-standard/paseto-spec/blob/master/docs/02-Implementation-Guide/02-Validators.md). pub fn disable_valid_at(&mut self) { self.validate_currently_valid = false; } /// Explicitly allow non-expiring tokens (i.e. the `exp` claim is missing). pub fn allow_non_expiring(&mut self) { self.allow_non_expiring = true; } /// Set the `valid_issuer` the claims should be validated against. pub fn validate_issuer_with(&mut self, valid_issuer: &str) { self.validate_issuer = Some(valid_issuer.to_string()); } /// Set the `valid_subject` the claims should be validated against. pub fn validate_subject_with(&mut self, valid_subject: &str) { self.validate_subject = Some(valid_subject.to_string()); } /// Set the `valid_audience` the claims should be validated against. pub fn validate_audience_with(&mut self, valid_audience: &str) { self.validate_audience = Some(valid_audience.to_string()); } /// Set the `valid_token_identifier` the claims should be validated against. pub fn validate_token_identifier_with(&mut self, valid_token_identifier: &str) { self.validate_token_identifier = Some(valid_token_identifier.to_string()); } ``` -------------------------------- ### Implement PASERK Formatting and Parsing Source: https://docs.rs/pasetors/0.7.8/src/pasetors/paserk.rs.html Implementations for formatting and parsing asymmetric public keys for different PASERK versions. ```rust #[cfg(feature = "v2")] impl FormatAsPaserk for AsymmetricPublicKey { fn fmt(&self, write: &mut dyn Write) -> core::fmt::Result { write.write_str("k2.public.")?; write.write_str(&encode_b64(self.as_bytes()).map_err(|_| core::fmt::Error)?) } } #[cfg(feature = "v2")] impl TryFrom<&str> for AsymmetricPublicKey { type Error = Error; fn try_from(value: &str) -> Result { Ok(Self { bytes: validate_paserk_string(value, "k2", "public", V2::PUBLIC_KEY)?, phantom: PhantomData, }) } } ``` ```rust #[cfg(feature = "v3")] impl FormatAsPaserk for AsymmetricPublicKey { fn fmt(&self, write: &mut dyn Write) -> core::fmt::Result { write.write_str("k3.public.")?; write.write_str(&encode_b64(self.as_bytes()).map_err(|_| core::fmt::Error)?) } } #[cfg(feature = "v3")] impl TryFrom<&str> for AsymmetricPublicKey { type Error = Error; fn try_from(value: &str) -> Result { Ok(Self { bytes: validate_paserk_string(value, "k3", "public", V3::PUBLIC_KEY)?, phantom: PhantomData, }) } } ``` ```rust #[cfg(feature = "v4")] impl FormatAsPaserk for AsymmetricPublicKey { fn fmt(&self, write: &mut dyn Write) -> core::fmt::Result { write.write_str("k4.public.")?; write.write_str(&encode_b64(self.as_bytes()).map_err(|_| core::fmt::Error)?) } } #[cfg(feature = "v4")] impl TryFrom<&str> for AsymmetricPublicKey { type Error = Error; fn try_from(value: &str) -> Result { Ok(Self { bytes: validate_paserk_string(value, "k4", "public", V4::PUBLIC_KEY)?, phantom: PhantomData, }) } } ``` -------------------------------- ### Set registered claims Source: https://docs.rs/pasetors/0.7.8/src/pasetors/lib.rs.html Shows how to manually set registered claims like issuer, subject, and expiration. ```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")?; ``` -------------------------------- ### PASETO Token with Custom Footer Claims Source: https://docs.rs/pasetors/0.7.8/index.html Demonstrates generating a PASETO token with a custom footer, including a registered `kid` claim derived from a public key ID and a custom claim. It also shows how to verify the token and extract the footer. ```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::::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::::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); ``` -------------------------------- ### SymmetricKey Blanket Implementations Source: https://docs.rs/pasetors/0.7.8/pasetors/keys/struct.SymmetricKey.html Blanket implementations for SymmetricKey, including Any, Borrow, and BorrowMut. ```APIDOC ## Blanket Implementations ### `impl Any for T` - `type_id(&self) -> TypeId`: Gets the `TypeId` of `self`. ### `impl Borrow for T` - `borrow(&self) -> &T`: Immutably borrows from an owned value. ### `impl BorrowMut for T` - `borrow_mut(&mut self) -> &mut T`: Mutably borrows from an owned value. ### `impl CloneToUninit for T` ``` -------------------------------- ### Serialize SymmetricKey with Serde Source: https://docs.rs/pasetors/0.7.8/src/pasetors/serde.rs.html Implement Serde's Serialize for SymmetricKey. This allows the symmetric key to be serialized into a paserk string format. Requires the 'paserk' feature. ```rust impl serde::Serialize for SymmetricKey where SymmetricKey: FormatAsPaserk, { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer, { use serde::ser::Error; let mut paserk_string = String::new(); self.fmt(&mut paserk_string).map_err(S::Error::custom)?; serializer.serialize_str(&paserk_string) } } ``` -------------------------------- ### TryFrom Implementation Source: https://docs.rs/pasetors/0.7.8/pasetors/errors/enum.Error.html Provides functionality to attempt conversion from one type to another, with error handling. ```APIDOC ## impl TryFrom for T ### Description Provides the `try_from` method for attempting conversions between types. ### Method `try_from` ### Endpoint N/A ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```json { "example": "Input value for conversion" } ``` ### Response #### Success Response (200) - **T** (type) - The successfully converted value. #### Error Response - **Error** (type) - The error type returned if conversion fails. This is defined as `Infallible`. ### Response Example ```json { "example": "Successfully converted value or an error" } ``` ``` -------------------------------- ### Convert AsymmetricSecretKey to AsymmetricPublicKey for V3 Source: https://docs.rs/pasetors/0.7.8/src/pasetors/version3.rs.html Provides a conversion from an `AsymmetricSecretKey` to an `AsymmetricPublicKey`. This is useful when you have a secret key and need to derive its corresponding public key for verification purposes. ```rust impl TryFrom<&AsymmetricSecretKey> for AsymmetricPublicKey { type Error = Error; fn try_from(value: &AsymmetricSecretKey) -> Result { let sk = SigningKey::from_bytes(value.as_bytes().into()).map_err(|_| Error::Key)?; AsymmetricPublicKey::::from(sk.verifying_key().to_encoded_point(true).as_bytes()) } } ``` -------------------------------- ### Manage Trusted Token Footers and Claims Source: https://docs.rs/pasetors/0.7.8/src/pasetors/token.rs.html Demonstrates how to add footers to trusted tokens and verify payload claims. ```rust #[test] fn test_get_footer_from_trusted() { let mut footer = Footer::default(); footer.add_additional("t", "v").unwrap(); let mut tt = TrustedToken::_new( "v3.local.", b"test msg", footer.to_string().unwrap().as_bytes(), b"", ) .unwrap(); assert!(Footer::try_from(&tt).is_ok()); tt.footer = Vec::::new(); assert!(Footer::try_from(&tt).is_err()); } #[test] fn test_trusted_claims() { let mut footer = Footer::default(); footer.add_additional("t", "v").unwrap(); let mut tt = TrustedToken::_new( "v3.local.", b"test msg", footer.to_string().unwrap().as_bytes(), b"", ) .unwrap(); let claims = Claims::new().unwrap(); tt.set_payload_claims(claims.clone()); assert_eq!(tt.payload_claims.unwrap(), claims); } ``` -------------------------------- ### Implement CloneToUninit for T (Nightly) Source: https://docs.rs/pasetors/0.7.8/pasetors/token/struct.Public.html Nightly-only experimental API for cloning a value into uninitialized memory. ```rust unsafe fn clone_to_uninit(&self, dest: *mut u8) ``` -------------------------------- ### Conversion Traits Overview Source: https://docs.rs/pasetors/0.7.8/pasetors/claims/struct.ClaimsValidationRules.html Documentation for standard conversion traits including From, Into, ToOwned, TryFrom, and TryInto. ```APIDOC ## From ### Description Trait for performing infallible conversions between types. ### Methods - **from(t: T) -> T**: Returns the argument unchanged. ## Into ### Description Trait for performing infallible conversions into another type. ### Methods - **into(self) -> U**: Calls U::from(self). ## ToOwned ### Description Trait for converting borrowed data into owned data. ### Associated Types - **Owned**: The resulting type after obtaining ownership. ### Methods - **to_owned(&self) -> T**: Creates owned data from borrowed data. - **clone_into(&self, target: &mut T)**: Uses borrowed data to replace owned data. ## TryFrom ### Description Trait for performing fallible conversions between types. ### Associated Types - **Error**: The type returned in the event of a conversion error. ### Methods - **try_from(value: U) -> Result**: Performs the conversion. ## TryInto ### Description Trait for performing fallible conversions into another type. ### Associated Types - **Error**: The type returned in the event of a conversion error. ### Methods - **try_into(self) -> Result**: Performs the conversion. ``` -------------------------------- ### TryInto Implementation Source: https://docs.rs/pasetors/0.7.8/pasetors/errors/enum.Error.html Provides functionality to attempt conversion into another type, with error handling. ```APIDOC ## impl TryInto for T ### Description Provides the `try_into` method for attempting conversions into other types. ### Method `try_into` ### Endpoint N/A ### Parameters None ### Request Body None ### Response #### Success Response (200) - **U** (type) - The successfully converted value. #### Error Response - **Error** (type) - The error type returned if conversion fails. This is defined as `>::Error`. ### Response Example ```json { "example": "Successfully converted value or an error" } ``` ``` -------------------------------- ### V3 Blanket Implementations Source: https://docs.rs/pasetors/0.7.8/pasetors/version3/struct.V3.html Details the blanket implementations for the V3 struct, including Any, Borrow, CloneToUninit, From, Into, Same, ToOwned, TryFrom, and TryInto. ```APIDOC ## Blanket Implementations for V3 ### impl Any for T #### fn type_id(&self) -> TypeId Gets the `TypeId` of `self`. ### impl Borrow for T #### fn borrow(&self) -> &T Immutably borrows from an owned value. ### impl BorrowMut for T #### fn borrow_mut(&mut self) -> &mut T Mutably borrows from an owned value. ### impl CloneToUninit for T #### unsafe fn clone_to_uninit(&self, dest: *mut u8) Performs copy-assignment from `self` to `dest`. ### impl From for T #### fn from(t: T) -> T Returns the argument unchanged. ### impl Into for T #### fn into(self) -> U Calls `U::from(self)`. ### impl Same for T #### type Output = T Should always be `Self`. ### impl ToOwned for T #### type Owned = T The resulting type after obtaining ownership. #### fn to_owned(&self) -> T Creates owned data from borrowed data, usually by cloning. #### fn clone_into(&self, target: &mut T) Uses borrowed data to replace owned data, usually by cloning. ### impl TryFrom for T #### type Error = Infallible The type returned in the event of a conversion error. #### fn try_from(value: U) -> Result>::Error> Performs the conversion. ### impl TryInto for T #### type Error = >::Error The type returned in the event of a conversion error. #### fn try_into(self) -> Result>::Error> Performs the conversion. ``` -------------------------------- ### Serialize AsymmetricSecretKey with Serde Source: https://docs.rs/pasetors/0.7.8/src/pasetors/serde.rs.html Implement Serde's Serialize for AsymmetricSecretKey. This allows the secret key to be serialized into a paserk string format. Requires the 'paserk' feature. ```rust impl serde::Serialize for AsymmetricSecretKey where AsymmetricSecretKey: FormatAsPaserk, { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer, { use serde::ser::Error; let mut paserk_string = String::new(); self.fmt(&mut paserk_string).map_err(S::Error::custom)?; serializer.serialize_str(&paserk_string) } } ``` -------------------------------- ### Derive Public Key from Secret Key Source: https://docs.rs/pasetors/0.7.8/src/pasetors/version2.rs.html Demonstrates deriving an AsymmetricPublicKey from an AsymmetricSecretKey and verifying equality. ```rust #[test] fn try_from_secret_to_public() { let kpv2 = AsymmetricKeyPair::::generate().unwrap(); let pubv2 = AsymmetricPublicKey::::try_from(&kpv2.secret).unwrap(); assert_eq!(pubv2.as_bytes(), kpv2.public.as_bytes()); assert_eq!(pubv2, kpv2.public); assert_eq!(&kpv2.secret.as_bytes()[32..], pubv2.as_bytes()); } ``` -------------------------------- ### Manage footers with registered and custom claims Source: https://docs.rs/pasetors/0.7.8/pasetors/index.html Demonstrates attaching a key ID and custom claims to a token footer. The footer can be retrieved and verified from a trusted token. ```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::::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::::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); ``` -------------------------------- ### Generate Keypair and Sign Token Source: https://docs.rs/pasetors/0.7.8/src/pasetors/version3.rs.html Generates an asymmetric key pair and signs a message to create a V3 Public Token. The token is then verified using the public key. ```rust const MESSAGE: &str = "{\"data\":\"this is a signed message\",\"exp\":\"2022-01-01T00:00:00+00:00\"}"; const FOOTER: &str = "{\"kid\":\"dYkISylxQeecEcHELfzF88UZrwbLolNiCdpzUHGw9Uqn\"}"; const VALID_PUBLIC_TOKEN: &str = "v3.public.eyJkYXRhIjoidGhpcyBpcyBhIHNpZ25lZCBtZXNzYWdlIiwiZXhwIjoiMjAyMi0wMS0wMVQwMDowMDowMCswMDowMCJ9ZWrbGZ6L0MDK72skosUaS0Dz7wJ_2bMcM6tOxFuCasO9GhwHrvvchqgXQNLQQyWzGC2wkr-VKII71AvkLpC8tJOrzJV1cap9NRwoFzbcXjzMZyxQ0wkshxZxx8ImmNWP.eyJraWQiOiJkWWtJU3lseFFlZWNFY0hFTGZ6Rjg4VVpyd2JMb2xOaUNkcHpVSEd3OVVxbiJ9"; #[test] fn test_gen_keypair() { let kp = AsymmetricKeyPair::::generate().unwrap(); let token = PublicToken::sign(&kp.secret, MESSAGE.as_bytes(), None, None).unwrap(); let ut = UntrustedToken::::try_from(&token).unwrap(); assert!(PublicToken::verify(&kp.public, &ut, None, None).is_ok()); } ``` -------------------------------- ### Manage Footers with Registered and Custom Claims Source: https://docs.rs/pasetors/0.7.8/src/pasetors/lib.rs.html Attach key IDs and custom data to token footers and verify them during token validation. ```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::::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::::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>(()) ``` -------------------------------- ### Try Convert TrustedToken to Footer Source: https://docs.rs/pasetors/0.7.8/pasetors/token/struct.TrustedToken.html Attempts to convert a `TrustedToken` reference into a `Footer`. Available on `crate feature`std` only. ```rust fn try_from(value: &TrustedToken) -> Result ``` -------------------------------- ### SymmetricKey Implementations Source: https://docs.rs/pasetors/0.7.8/pasetors/keys/struct.SymmetricKey.html Core implementations for the SymmetricKey struct. ```APIDOC ## impl SymmetricKey ### `from(bytes: &[u8]) -> Result` Create a `SymmetricKey` from `bytes`. ### `as_bytes(&self) -> &[u8]` Return this as a byte-slice. ``` -------------------------------- ### Run Wycheproof Point Compression Tests Source: https://docs.rs/pasetors/0.7.8/src/pasetors/version3.rs.html Executes the `wycheproof_point_compression` function with specific test vector file paths for ECDSA Secp384r1 with SHA3-384 and SHA384. ```rust wycheproof_point_compression( "./test_vectors/wycheproof/ecdsa_secp384r1_sha3_384_test.json", ); wycheproof_point_compression("./test_vectors/wycheproof/ecdsa_secp384r1_sha384_test.json"); ``` -------------------------------- ### SymmetricKey Management Source: https://docs.rs/pasetors/0.7.8/src/pasetors/keys.rs.html Methods for creating and interacting with symmetric keys used for .local tokens. ```APIDOC ## SymmetricKey ### Description A symmetric key used for .local tokens, given a version V. ### Methods - **from(bytes: &[u8]) -> Result** - Creates a SymmetricKey from the provided byte slice. Validates the key against the specified version. - **as_bytes() -> &[u8]** - Returns the key as a byte-slice. ``` -------------------------------- ### Parse Valid V2 Local Token (With Footer) Source: https://docs.rs/pasetors/0.7.8/src/pasetors/token.rs.html Demonstrates successful parsing of a V2 local Paseto token that includes a footer. The untrusted footer content is asserted to match the expected JSON. ```rust // "2-E-1" let valid_no_footer = "v2.local.97TTOvgwIxNGvV80XKiGZg_kD3tsXM_-qB4dZGHOeN1cTkgQ4PnW8888l802W8d9AvEGnoNBY3BnqHORy8a5cC8aKpbA0En8XELw2yDk2f1sVODyfnDbi6rEGMY3pSfCbLWMM2oHJxvlEl2XbQ"; // "2-E-5" let valid_with_footer = "v2.local.5K4SCXNhItIhyNuVIZcwrdtaDKiyF81-eWHScuE0idiVqCo72bbjo07W05mqQkhLZdVbxEa5I_u5sgVk1QLkcWEcOSlLHwNpCkvmGGlbCdNExn6Qclw3qTKIIl5-zSLIrxZqOLwcFLYbVK1SrQ.eyJraWQiOiJ6VmhNaVBCUDlmUmYyc25FY1Q3Z0ZUaW9lQTlDT2NOeTlEZmdMMVc2MGhhTiJ9"; let untrusted_no_footer = UntrustedToken::::try_from(valid_no_footer).unwrap(); let untrusted_with_footer = UntrustedToken::::try_from(valid_with_footer).unwrap(); // Note: We don't test for untrusted message, since it is encrypted. assert_eq!( untrusted_with_footer.untrusted_footer(), b"{\"kid\":\"zVhMiPBC9fRf2snEcT7gFTioeA9COcNy9DfgL1W60haN\"}" ); ```