Enum biscuit::jwe::Compact

source ·
pub enum Compact<T, H> {
    Decrypted {
        header: Header<H>,
        payload: T,
    },
    Encrypted(Compact),
}
Expand description

Compact representation of a JWE, or an encrypted JWT

This representation contains a payload of type T with custom headers provided by type H. In general you should use a JWE with a JWS. That is, you should sign your JSON Web Token to create a JWS, and then encrypt the signed JWS.

Nonce/Initialization Vectors for AES GCM encryption

When encrypting tokens with AES GCM, you must take care not to reuse the nonce for the same key. You can keep track of this by simply treating the nonce as a 96 bit counter and incrementing it every time you encrypt something new.

Examples

Encrypting a JWS/JWT

See the example code in the biscuit::JWE type alias.

Encrypting a string payload with A256GCMKW and A256GCM

use std::str;
use biscuit::Empty;
use biscuit::jwk::JWK;
use biscuit::jwe;
use biscuit::jwa::{EncryptionOptions, KeyManagementAlgorithm, ContentEncryptionAlgorithm};

let payload = "The true sign of intelligence is not knowledge but imagination.";
// You would usually have your own AES key for this, but we will use a zeroed key as an example
let key: JWK<Empty> = JWK::new_octet_key(&vec![0; 256 / 8], Default::default());

// Construct the JWE
let jwe = jwe::Compact::new_decrypted(
    From::from(jwe::RegisteredHeader {
        cek_algorithm: KeyManagementAlgorithm::A256GCMKW,
        enc_algorithm: ContentEncryptionAlgorithm::A256GCM,
        ..Default::default()
    }),
    payload.as_bytes().to_vec(),
);

// We need to create an `EncryptionOptions` with a nonce for AES GCM encryption.
// You must take care NOT to reuse the nonce. You can simply treat the nonce as a 96 bit
// counter that is incremented after every use
let mut nonce_counter = num_bigint::BigUint::from_bytes_le(&vec![0; 96 / 8]);
// Make sure it's no more than 96 bits!
assert!(nonce_counter.bits() <= 96);
let mut nonce_bytes = nonce_counter.to_bytes_le();
// We need to ensure it is exactly 96 bits
nonce_bytes.resize(96/8, 0);
let options = EncryptionOptions::AES_GCM { nonce: nonce_bytes };

// Encrypt
let encrypted_jwe = jwe.encrypt(&key, &options).unwrap();

// Decrypt
let decrypted_jwe = encrypted_jwe
    .decrypt(
        &key,
        KeyManagementAlgorithm::A256GCMKW,
        ContentEncryptionAlgorithm::A256GCM,
    )
    .unwrap();

let decrypted_payload: &Vec<u8> = decrypted_jwe.payload().unwrap();
let decrypted_str = str::from_utf8(&*decrypted_payload).unwrap();
assert_eq!(decrypted_str, payload);

// Don't forget to increment the nonce!
nonce_counter = nonce_counter + 1u8;

Variants§

§

Decrypted

Fields

§header: Header<H>

Embedded header

§payload: T

Payload, usually a signed/unsigned JWT

Decrypted form of the JWE. This variant cannot be serialized or deserialized and will return an error.

§

Encrypted(Compact)

Encrypted JWT. Use this form to send to your clients

Implementations§

source§

impl<T, H> Compact<T, H>where T: CompactPart, H: Serialize + DeserializeOwned + Clone,

source

pub fn new_decrypted(header: Header<H>, payload: T) -> Self

Create a new encrypted JWE

source

pub fn new_encrypted(token: &str) -> Self

Create a new encrypted JWE

source

pub fn into_encrypted<K: Serialize + DeserializeOwned>( self, key: &JWK<K>, options: &EncryptionOptions ) -> Result<Self, Error>

Consumes self and encrypt it. If the token is already encrypted, this is a no-op.

You will need to provide a jwa::EncryptionOptions that will differ based on your chosen algorithms.

If your cek_algorithm is not dir or direct, the options provided will be used to encrypt your content encryption key.

If your cek_algorithm is dir or Direct, then the options will be used to encrypt your content directly.

source

pub fn encrypt<K: Serialize + DeserializeOwned>( &self, key: &JWK<K>, options: &EncryptionOptions ) -> Result<Self, Error>

Encrypt an Decrypted JWE.

You will need to provide a jwa::EncryptionOptions that will differ based on your chosen algorithms.

If your cek_algorithm is not dir or direct, the options provided will be used to encrypt your content encryption key.

If your cek_algorithm is dir or Direct, then the options will be used to encrypt your content directly.

source

pub fn into_decrypted<K: Serialize + DeserializeOwned>( self, key: &JWK<K>, cek_alg: KeyManagementAlgorithm, enc_alg: ContentEncryptionAlgorithm ) -> Result<Self, Error>

Consumes self and decrypt it. If the token is already decrypted, this is a no-op.

source

pub fn decrypt<K: Serialize + DeserializeOwned>( &self, key: &JWK<K>, cek_alg: KeyManagementAlgorithm, enc_alg: ContentEncryptionAlgorithm ) -> Result<Self, Error>

Decrypt an encrypted JWE. Provide the expected algorithms to mitigate an attacker modifying the fields

source

pub fn encrypted(&self) -> Result<&Compact, Error>

Convenience method to get a reference to the encrypted payload

source

pub fn encrypted_mut(&mut self) -> Result<&mut Compact, Error>

Convenience method to get a mutable reference to the encrypted payload

source

pub fn payload(&self) -> Result<&T, Error>

Convenience method to get a reference to the payload from an Decrypted JWE

source

pub fn payload_mut(&mut self) -> Result<&mut T, Error>

Convenience method to get a mutable reference to the payload from an Decrypted JWE

source

pub fn header(&self) -> Result<&Header<H>, Error>

Convenience method to get a reference to the header from an Decrypted JWE

source

pub fn header_mut(&mut self) -> Result<&mut Header<H>, Error>

Convenience method to get a reference to the header from an Decrypted JWE

source

pub fn unwrap_decrypted(self) -> (Header<H>, T)

Consumes self, and move the payload and header out and return them as a tuple

Panics

Panics if the JWE is not decrypted

source

pub fn unwrap_encrypted(self) -> Compact

Consumes self, and move the encrypted Compact serialization out and return it

Panics

Panics if the JWE is not encrypted

source§

impl<P, H> Compact<ClaimsSet<P>, H>where ClaimsSet<P>: CompactPart, H: Serialize + DeserializeOwned + Clone,

Convenience implementation for a Compact that contains a ClaimsSet

source

pub fn validate(&self, options: ValidationOptions) -> Result<(), Error>

Validate the temporal claims in the decoded token

If None is provided for options, the defaults will apply.

By default, no temporal claims (namely iat, exp, nbf) are required, and they will pass validation if they are missing.

Trait Implementations§

source§

impl<T: Clone, H: Clone> Clone for Compact<T, H>

source§

fn clone(&self) -> Compact<T, H>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<T: Debug, H: Debug> Debug for Compact<T, H>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'de, T, H> Deserialize<'de> for Compact<T, H>

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<T: PartialEq, H: PartialEq> PartialEq for Compact<T, H>

source§

fn eq(&self, other: &Compact<T, H>) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl<T, H> Serialize for Compact<T, H>

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
source§

impl<T: Eq, H: Eq> Eq for Compact<T, H>

source§

impl<T, H> StructuralEq for Compact<T, H>

source§

impl<T, H> StructuralPartialEq for Compact<T, H>

Auto Trait Implementations§

§

impl<T, H> RefUnwindSafe for Compact<T, H>where H: RefUnwindSafe, T: RefUnwindSafe,

§

impl<T, H> Send for Compact<T, H>where H: Send, T: Send,

§

impl<T, H> Sync for Compact<T, H>where H: Sync, T: Sync,

§

impl<T, H> Unpin for Compact<T, H>where H: Unpin, T: Unpin,

§

impl<T, H> UnwindSafe for Compact<T, H>where H: UnwindSafe, T: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Qwhere Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Qwhere Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for Twhere T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> DeserializeOwned for Twhere T: for<'de> Deserialize<'de>,