1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
use crate::{verify_bytes, DecodedJWS, DecodedSigningBytes, Error, Header};
use ssi_claims_core::{
    ClaimsValidity, InvalidProof, ProofValidationError, ProofValidity, ResolverProvider,
    ValidateClaims, ValidateProof, VerifiableClaims,
};
use ssi_jwk::JWKResolver;
use std::{
    borrow::{Borrow, Cow},
    ops::Deref,
};

pub trait ValidateJWSHeader<E> {
    fn validate_jws_header(&self, env: &E, header: &Header) -> ClaimsValidity;
}

impl<E> ValidateJWSHeader<E> for [u8] {
    fn validate_jws_header(&self, _env: &E, _header: &Header) -> ClaimsValidity {
        Ok(())
    }
}

impl<'a, E, T: ?Sized + ToOwned + ValidateJWSHeader<E>> ValidateJWSHeader<E> for Cow<'a, T> {
    fn validate_jws_header(&self, env: &E, header: &Header) -> ClaimsValidity {
        self.as_ref().validate_jws_header(env, header)
    }
}

impl<E, T: ValidateClaims<E, JWSSignature> + ValidateJWSHeader<E>> ValidateClaims<E, JWSSignature>
    for DecodedSigningBytes<T>
{
    fn validate_claims(&self, env: &E, signature: &JWSSignature) -> ClaimsValidity {
        self.payload.validate_jws_header(env, &self.header)?;
        self.payload.validate_claims(env, signature)
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct JWSSignature(Vec<u8>);

impl JWSSignature {
    pub fn as_bytes(&self) -> &[u8] {
        &self.0
    }

    pub fn into_bytes(self) -> Vec<u8> {
        self.0
    }
}

impl From<Vec<u8>> for JWSSignature {
    fn from(value: Vec<u8>) -> Self {
        Self(value)
    }
}

impl From<JWSSignature> for Vec<u8> {
    fn from(value: JWSSignature) -> Self {
        value.into_bytes()
    }
}

impl Deref for JWSSignature {
    type Target = [u8];

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl AsRef<[u8]> for JWSSignature {
    fn as_ref(&self) -> &[u8] {
        &self.0
    }
}

impl Borrow<[u8]> for JWSSignature {
    fn borrow(&self) -> &[u8] {
        &self.0
    }
}

impl<T> VerifiableClaims for DecodedJWS<T> {
    type Claims = DecodedSigningBytes<T>;
    type Proof = JWSSignature;

    fn claims(&self) -> &Self::Claims {
        &self.signing_bytes
    }

    fn proof(&self) -> &Self::Proof {
        &self.signature
    }
}

impl<V, T> ValidateProof<V, DecodedSigningBytes<T>> for JWSSignature
where
    V: ResolverProvider,
    V::Resolver: JWKResolver,
{
    async fn validate_proof<'a>(
        &'a self,
        verifier: &'a V,
        claims: &'a DecodedSigningBytes<T>,
    ) -> Result<ProofValidity, ProofValidationError> {
        let key = verifier
            .resolver()
            .fetch_public_jwk(claims.header.key_id.as_deref())
            .await?;
        match verify_bytes(claims.header.algorithm, &claims.bytes, &key, &self.0) {
            Ok(()) => Ok(Ok(())),
            Err(Error::InvalidSignature) => Ok(Err(InvalidProof::Signature)),
            Err(_) => Err(ProofValidationError::InvalidSignature),
        }
    }
}