jose_jws/
lib.rs

1// SPDX-FileCopyrightText: 2022 Profian Inc. <opensource@profian.com>
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3
4#![no_std]
5#![cfg_attr(docsrs, feature(doc_auto_cfg))]
6#![doc = include_str!("../README.md")]
7#![doc(
8    html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg",
9    html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg"
10)]
11#![forbid(unsafe_code)]
12#![warn(
13    clippy::panic,
14    clippy::panic_in_result_fn,
15    clippy::unwrap_used,
16    missing_docs,
17    rust_2018_idioms,
18    unused_lifetimes,
19    unused_qualifications
20)]
21
22extern crate alloc;
23
24pub mod crypto;
25
26mod compact;
27mod head;
28
29pub use head::{Protected, Unprotected};
30
31use alloc::{vec, vec::Vec};
32
33use jose_b64::serde::{Bytes, Json};
34use serde::{Deserialize, Serialize};
35
36/// A JSON Web Signature representation
37#[derive(Clone, Debug, Serialize, Deserialize)]
38#[non_exhaustive]
39#[allow(clippy::large_enum_variant)]
40#[serde(untagged)]
41pub enum Jws {
42    /// General Serialization. This is
43    General(General),
44
45    /// Flattened Serialization
46    Flattened(Flattened),
47}
48
49impl From<General> for Jws {
50    fn from(value: General) -> Self {
51        Jws::General(value)
52    }
53}
54
55impl From<Flattened> for Jws {
56    fn from(value: Flattened) -> Self {
57        Jws::Flattened(value)
58    }
59}
60
61/// General Serialization
62///
63/// This is the usual JWS form, which allows multiple signatures to be
64/// specified.
65///
66/// ```json
67/// {
68///     "payload":"<payload contents>",
69///     "signatures":[
70///      {"protected":"<integrity-protected header 1 contents>",
71///       "header":<non-integrity-protected header 1 contents>,
72///       "signature":"<signature 1 contents>"},
73///      ...
74///      {"protected":"<integrity-protected header N contents>",
75///       "header":<non-integrity-protected header N contents>,
76///       "signature":"<signature N contents>"}]
77/// }
78/// ```
79#[derive(Clone, Debug, Serialize, Deserialize)]
80pub struct General {
81    /// The payload of the signature.
82    pub payload: Option<Bytes>,
83
84    /// The signatures over the payload.
85    pub signatures: Vec<Signature>,
86}
87
88impl From<Flattened> for General {
89    fn from(value: Flattened) -> Self {
90        Self {
91            payload: value.payload,
92            signatures: vec![value.signature],
93        }
94    }
95}
96
97/// Flattened Serialization
98///
99/// This is similar to the general serialization but is more compact, only
100/// supporting one signature.
101///
102/// ```json
103/// {
104///     "payload":"<payload contents>",
105///     "protected":"<integrity-protected header contents>",
106///     "header":<non-integrity-protected header contents>,
107///     "signature":"<signature contents>"
108/// }
109/// ```
110#[derive(Clone, Debug, Serialize, Deserialize)]
111pub struct Flattened {
112    /// The payload of the signature.
113    pub payload: Option<Bytes>,
114
115    /// The signature over the payload.
116    #[serde(flatten)]
117    pub signature: Signature,
118}
119
120/// A Signature
121#[derive(Clone, Debug, Serialize, Deserialize)]
122pub struct Signature {
123    /// The JWS Unprotected Header
124    pub header: Option<Unprotected>,
125
126    /// The JWS Protected Header
127    pub protected: Option<Json<Protected>>,
128
129    /// The Signature Bytes
130    pub signature: Bytes,
131}