use std::marker::PhantomData;
use bytes::Bytes;
use serde::Serialize;
use signature::SignatureEncoding;
use crate::{
algorithms::{DynJsonWebAlgorithm, SignatureBytes},
base64data::Base64Signature,
jose,
};
pub trait MaybeSigned {
type HeaderState;
type Header;
#[doc(hidden)]
fn header(&self) -> &jose::Header<Self::Header, Self::HeaderState>;
#[doc(hidden)]
fn header_mut(&mut self) -> &mut jose::Header<Self::Header, Self::HeaderState>;
fn is_signed(&self) -> bool;
fn is_verified(&self) -> bool;
}
pub trait HasSignature: MaybeSigned {
type Signature: SignatureEncoding;
fn signature(&self) -> &Self::Signature;
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Unsigned<H> {
pub(super) header: jose::Header<H, jose::UnsignedHeader>,
}
impl<H> MaybeSigned for Unsigned<H> {
type HeaderState = jose::UnsignedHeader;
type Header = H;
fn header(&self) -> &jose::Header<H, Self::HeaderState> {
&self.header
}
fn is_signed(&self) -> bool {
false
}
fn is_verified(&self) -> bool {
false
}
fn header_mut(&mut self) -> &mut jose::Header<Self::Header, Self::HeaderState> {
&mut self.header
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
#[serde(bound(serialize = "H: Serialize, Sig: Serialize",))]
pub struct Signed<H, Alg, Sig = SignatureBytes>
where
Alg: DynJsonWebAlgorithm + ?Sized,
{
pub(super) header: jose::Header<H, jose::SignedHeader>,
pub(super) signature: Sig,
#[serde(skip)]
pub(super) _phantom_key: PhantomData<Alg>,
}
impl<H, Alg, Sig> HasSignature for Signed<H, Alg, Sig>
where
Alg: DynJsonWebAlgorithm + ?Sized,
Sig: SignatureEncoding,
{
type Signature = Sig;
fn signature(&self) -> &Self::Signature {
&self.signature
}
}
impl<H, Alg, Sig> MaybeSigned for Signed<H, Alg, Sig>
where
Alg: DynJsonWebAlgorithm + ?Sized,
{
type HeaderState = jose::SignedHeader;
type Header = H;
fn header(&self) -> &jose::Header<H, Self::HeaderState> {
&self.header
}
fn header_mut(&mut self) -> &mut jose::Header<Self::Header, Self::HeaderState> {
&mut self.header
}
fn is_signed(&self) -> bool {
true
}
fn is_verified(&self) -> bool {
true
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
#[serde(bound(serialize = "H: Serialize, Sig: Serialize",))]
pub struct Verified<H, Alg, Sig = SignatureBytes>
where
Alg: DynJsonWebAlgorithm + ?Sized,
{
pub(super) header: jose::Header<H, jose::SignedHeader>,
pub(super) signature: Sig,
#[serde(skip)]
pub(super) _phantom_key: PhantomData<Alg>,
}
impl<H, Alg, Sig> MaybeSigned for Verified<H, Alg, Sig>
where
Alg: DynJsonWebAlgorithm + ?Sized,
{
type HeaderState = jose::SignedHeader;
type Header = H;
fn header_mut(&mut self) -> &mut jose::Header<Self::Header, Self::HeaderState> {
&mut self.header
}
fn header(&self) -> &jose::Header<H, Self::HeaderState> {
&self.header
}
fn is_signed(&self) -> bool {
true
}
fn is_verified(&self) -> bool {
true
}
}
impl<H, Alg, Sig> HasSignature for Verified<H, Alg, Sig>
where
Alg: DynJsonWebAlgorithm + ?Sized,
Sig: SignatureEncoding,
{
type Signature = Sig;
fn signature(&self) -> &Self::Signature {
&self.signature
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Unverified<H> {
pub(super) payload: Bytes,
pub(super) header: jose::Header<H, jose::RenderedHeader>,
pub(super) signature: Base64Signature<SignatureBytes>,
}
impl<H> MaybeSigned for Unverified<H> {
type HeaderState = jose::RenderedHeader;
type Header = H;
fn header_mut(&mut self) -> &mut jose::Header<Self::Header, Self::HeaderState> {
&mut self.header
}
fn header(&self) -> &jose::Header<H, Self::HeaderState> {
&self.header
}
fn is_signed(&self) -> bool {
true
}
fn is_verified(&self) -> bool {
false
}
}
impl<H> HasSignature for Unverified<H> {
type Signature = SignatureBytes;
fn signature(&self) -> &Self::Signature {
&self.signature.0
}
}