ssi_verification_methods/methods/unspecified/
solana_method_2021.rs

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