ssi_verification_methods/methods/w3c/
rsa_verification_key_2018.rs

1use std::{borrow::Cow, hash::Hash};
2
3use iref::{Iri, IriBuf, UriBuf};
4use serde::{Deserialize, Serialize};
5use ssi_claims_core::{InvalidProof, MessageSignatureError, ProofValidationError, ProofValidity};
6use ssi_jwk::JWK;
7use ssi_verification_methods_core::{JwkVerificationMethod, VerificationMethodSet};
8use static_iref::iri;
9
10use crate::{
11    ExpectedType, GenericVerificationMethod, InvalidVerificationMethod, TypedVerificationMethod,
12    VerificationMethod,
13};
14
15pub const RSA_VERIFICATION_KEY_2018_TYPE: &str = "RsaVerificationKey2018";
16
17// pub const RSA_VERIFICATION_KEY_2018_IRI: &Iri =
18//     iri!("https://w3id.org/security#RsaVerificationKey2018");
19
20/// RSA verification key 2018.
21///
22/// To be used with the [RSA Signature Suite 2018][1].
23///
24/// See: <https://www.w3.org/TR/did-spec-registries/#rsaverificationkey2018>
25///
26/// [1]: <https://w3c-ccg.github.io/lds-rsa2018/>
27#[derive(
28    Debug,
29    Clone,
30    PartialEq,
31    Eq,
32    Hash,
33    Serialize,
34    Deserialize,
35    linked_data::Serialize,
36    linked_data::Deserialize,
37)]
38#[serde(tag = "type", rename = "RsaVerificationKey2018")]
39#[ld(prefix("sec" = "https://w3id.org/security#"))]
40#[ld(type = "sec:RsaVerificationKey2018")]
41pub struct RsaVerificationKey2018 {
42    /// Key identifier.
43    #[ld(id)]
44    pub id: IriBuf,
45
46    /// Key crontroller.
47    #[ld("sec:controller")]
48    pub controller: UriBuf,
49
50    /// Public JSON Web Key.
51    #[serde(rename = "publicKeyJwk")]
52    #[ld("sec:publicKeyJwk")]
53    pub public_key: Box<JWK>,
54}
55
56impl RsaVerificationKey2018 {
57    pub const NAME: &'static str = RSA_VERIFICATION_KEY_2018_TYPE;
58    pub const IRI: &'static Iri = iri!("https://w3id.org/security#RsaVerificationKey2018");
59
60    pub fn public_key_jwk(&self) -> &JWK {
61        &self.public_key
62    }
63
64    pub fn sign_bytes(
65        &self,
66        data: &[u8],
67        secret_key: &JWK,
68    ) -> Result<Vec<u8>, MessageSignatureError> {
69        ssi_jws::sign_bytes(ssi_jwk::Algorithm::RS256, data, secret_key)
70            .map_err(|_| MessageSignatureError::InvalidSecretKey)
71    }
72
73    pub fn verify_bytes(
74        &self,
75        data: &[u8],
76        signature: &[u8],
77    ) -> Result<ProofValidity, ProofValidationError> {
78        let result =
79            ssi_jws::verify_bytes(ssi_jwk::Algorithm::RS256, data, &self.public_key, signature);
80        match result {
81            Ok(()) => Ok(Ok(())),
82            Err(ssi_jws::Error::InvalidSignature) => Ok(Err(InvalidProof::Signature)),
83            Err(_) => Err(ProofValidationError::InvalidSignature),
84        }
85    }
86}
87
88impl VerificationMethod for RsaVerificationKey2018 {
89    /// Returns the identifier of the key.
90    fn id(&self) -> &Iri {
91        self.id.as_iri()
92    }
93
94    /// Returns an URI to the key controller.
95    fn controller(&self) -> Option<&Iri> {
96        Some(self.controller.as_iri())
97    }
98}
99
100impl VerificationMethodSet for RsaVerificationKey2018 {
101    type TypeSet = &'static str;
102
103    fn type_set() -> Self::TypeSet {
104        Self::NAME
105    }
106}
107
108impl TypedVerificationMethod for RsaVerificationKey2018 {
109    fn expected_type() -> Option<ExpectedType> {
110        Some(RSA_VERIFICATION_KEY_2018_TYPE.to_string().into())
111    }
112
113    fn type_match(ty: &str) -> bool {
114        ty == RSA_VERIFICATION_KEY_2018_TYPE
115    }
116
117    /// Returns the type of the key.
118    fn type_(&self) -> &str {
119        RSA_VERIFICATION_KEY_2018_TYPE
120    }
121}
122
123impl JwkVerificationMethod for RsaVerificationKey2018 {
124    fn to_jwk(&self) -> Cow<JWK> {
125        Cow::Borrowed(self.public_key_jwk())
126    }
127}
128
129impl TryFrom<GenericVerificationMethod> for RsaVerificationKey2018 {
130    type Error = InvalidVerificationMethod;
131
132    fn try_from(mut m: GenericVerificationMethod) -> Result<Self, Self::Error> {
133        Ok(Self {
134            id: m.id,
135            controller: m.controller,
136            public_key: Box::new(
137                serde_json::from_value(
138                    m.properties.remove("publicKeyJwk").ok_or_else(|| {
139                        InvalidVerificationMethod::missing_property("publicKeyJwk")
140                    })?,
141                )
142                .map_err(|_| InvalidVerificationMethod::invalid_property("publicKeyJwk"))?,
143            ),
144        })
145    }
146}