1mod w3c;
2use std::borrow::Cow;
3
4use ssi_claims_core::MessageSignatureError;
5use ssi_jwk::JWK;
6use ssi_verification_methods_core::{
7 GenericVerificationMethod, JwkVerificationMethod, MaybeJwkVerificationMethod, SigningMethod,
8};
9pub use w3c::*;
10
11mod unspecified;
12pub use unspecified::*;
13
14ssi_verification_methods_core::complete_verification_method_union! {
15 pub enum AnyMethod, AnyMethodType, AnyMethodTypeRef {
16 Multikey,
18
19 JsonWebKey2020,
21
22 #[cfg(feature = "rsa")]
24 RsaVerificationKey2018,
25
26 #[cfg(feature = "ed25519")]
28 Ed25519VerificationKey2018,
29
30 #[cfg(feature = "ed25519")]
32 Ed25519VerificationKey2020,
33
34 #[cfg(feature = "secp256k1")]
35 EcdsaSecp256k1VerificationKey2019,
36
37 #[cfg(feature = "secp256k1")]
38 EcdsaSecp256k1RecoveryMethod2020,
39
40 #[cfg(feature = "secp256r1")]
41 EcdsaSecp256r1VerificationKey2019,
42
43 #[cfg(all(feature = "tezos", feature = "ed25519"))]
44 Ed25519PublicKeyBLAKE2BDigestSize20Base58CheckEncoded2021,
45
46 #[cfg(all(feature = "tezos", feature = "secp256r1"))]
47 P256PublicKeyBLAKE2BDigestSize20Base58CheckEncoded2021,
48
49 #[cfg(feature = "tezos")]
50 TezosMethod2021,
51
52 #[cfg(feature = "aleo")]
53 AleoMethod2021,
54
55 BlockchainVerificationMethod2021,
56
57 #[cfg(all(feature = "eip712", feature = "secp256k1"))]
58 Eip712Method2021,
59
60 #[cfg(feature = "solana")]
61 SolanaMethod2021
62 }
63}
64
65impl AnyMethod {
66 pub fn public_key_jwk(&self) -> Option<Cow<JWK>> {
70 match self {
71 #[cfg(feature = "rsa")]
72 Self::RsaVerificationKey2018(m) => Some(Cow::Borrowed(m.public_key_jwk())),
73 #[cfg(feature = "ed25519")]
74 Self::Ed25519VerificationKey2018(m) => Some(Cow::Owned(m.public_key_jwk())),
75 #[cfg(feature = "ed25519")]
76 Self::Ed25519VerificationKey2020(m) => Some(Cow::Owned(m.public_key_jwk())),
77 #[cfg(feature = "secp256k1")]
78 Self::EcdsaSecp256k1VerificationKey2019(m) => Some(m.public_key_jwk()),
79 #[cfg(feature = "secp256k1")]
80 Self::EcdsaSecp256k1RecoveryMethod2020(m) => m.public_key_jwk(),
81 #[cfg(feature = "secp256r1")]
82 Self::EcdsaSecp256r1VerificationKey2019(m) => Some(Cow::Owned(m.public_key_jwk())),
83 Self::JsonWebKey2020(m) => Some(Cow::Borrowed(m.public_key_jwk())),
84 Self::Multikey(m) => m.public_key_jwk().map(Cow::Owned),
85 #[cfg(all(feature = "tezos", feature = "ed25519"))]
86 Self::Ed25519PublicKeyBLAKE2BDigestSize20Base58CheckEncoded2021(_) => None,
87 #[cfg(all(feature = "tezos", feature = "secp256r1"))]
88 Self::P256PublicKeyBLAKE2BDigestSize20Base58CheckEncoded2021(_) => None,
89 #[cfg(feature = "tezos")]
90 Self::TezosMethod2021(m) => m.public_key_jwk().map(Cow::Borrowed),
91 #[cfg(feature = "aleo")]
92 Self::AleoMethod2021(_) => None,
93 Self::BlockchainVerificationMethod2021(_) => None,
94 #[cfg(all(feature = "eip712", feature = "secp256k1"))]
95 Self::Eip712Method2021(_) => None,
96 #[cfg(feature = "solana")]
97 Self::SolanaMethod2021(m) => Some(Cow::Borrowed(m.public_key_jwk())),
98 _ => None,
99 }
100 }
101}
102
103impl From<AnyMethod> for GenericVerificationMethod {
104 fn from(value: AnyMethod) -> Self {
105 let json = serde_json::to_value(value).unwrap();
107 serde_json::from_value(json).unwrap()
108 }
109}
110
111impl MaybeJwkVerificationMethod for AnyMethod {
112 fn try_to_jwk(&self) -> Option<Cow<JWK>> {
113 self.public_key_jwk()
114 }
115}
116
117impl SigningMethod<JWK, ssi_crypto::Algorithm> for AnyMethod {
118 fn sign_bytes(
119 &self,
120 secret: &JWK,
121 algorithm: ssi_crypto::AlgorithmInstance,
122 bytes: &[u8],
123 ) -> Result<Vec<u8>, MessageSignatureError> {
124 match self {
125 #[cfg(feature = "rsa")]
126 Self::RsaVerificationKey2018(m) => m.sign_bytes(bytes, secret),
127 #[cfg(feature = "ed25519")]
128 Self::Ed25519VerificationKey2018(m) => {
129 m.sign_bytes(secret, algorithm.try_into()?, bytes)
130 }
131 #[cfg(feature = "ed25519")]
132 Self::Ed25519VerificationKey2020(m) => match algorithm {
133 ssi_crypto::AlgorithmInstance::EdDSA => m.sign_bytes(secret, bytes),
134 _ => Err(MessageSignatureError::UnsupportedAlgorithm(
135 algorithm.algorithm().to_string(),
136 )),
137 },
138 #[cfg(feature = "secp256k1")]
139 Self::EcdsaSecp256k1VerificationKey2019(m) => match algorithm {
140 ssi_crypto::AlgorithmInstance::ES256K => m.sign_bytes(
141 secret,
142 ecdsa_secp_256k1_verification_key_2019::DigestFunction::Sha256,
143 bytes,
144 ),
145 _ => Err(MessageSignatureError::UnsupportedAlgorithm(
146 algorithm.algorithm().to_string(),
147 )),
148 },
149 #[cfg(feature = "secp256k1")]
150 Self::EcdsaSecp256k1RecoveryMethod2020(m) => match algorithm {
151 ssi_crypto::AlgorithmInstance::ES256KR => {
152 SigningMethod::<_, ssi_crypto::algorithm::ES256KR>::sign_bytes(
153 m,
154 secret,
155 ssi_crypto::algorithm::ES256KR,
156 bytes,
157 )
158 }
159 ssi_crypto::AlgorithmInstance::ESKeccakKR => {
160 SigningMethod::<_, ssi_crypto::algorithm::ESKeccakKR>::sign_bytes(
161 m,
162 secret,
163 ssi_crypto::algorithm::ESKeccakKR,
164 bytes,
165 )
166 }
167 _ => Err(MessageSignatureError::UnsupportedAlgorithm(
168 algorithm.algorithm().to_string(),
169 )),
170 },
171 #[cfg(feature = "secp256r1")]
172 Self::EcdsaSecp256r1VerificationKey2019(m) => match algorithm {
173 ssi_crypto::AlgorithmInstance::ES256 => m.sign_bytes(secret, bytes),
174 _ => Err(MessageSignatureError::UnsupportedAlgorithm(
175 algorithm.algorithm().to_string(),
176 )),
177 },
178 Self::JsonWebKey2020(m) => m.sign_bytes(secret, Some(algorithm.try_into()?), bytes),
179 Self::Multikey(m) => {
180 SigningMethod::<_, ssi_crypto::Algorithm>::sign_bytes(m, secret, algorithm, bytes)
181 }
182 #[cfg(all(feature = "tezos", feature = "ed25519"))]
183 Self::Ed25519PublicKeyBLAKE2BDigestSize20Base58CheckEncoded2021(m) => {
184 m.sign_bytes(secret, algorithm.try_into()?, bytes)
185 }
186 #[cfg(all(feature = "tezos", feature = "secp256r1"))]
187 Self::P256PublicKeyBLAKE2BDigestSize20Base58CheckEncoded2021(m) => {
188 m.sign_bytes(secret, algorithm.try_into()?, bytes)
189 }
190 #[cfg(feature = "tezos")]
191 Self::TezosMethod2021(m) => m.sign_bytes(secret, algorithm.try_into()?, bytes),
192 #[cfg(feature = "aleo")]
193 Self::AleoMethod2021(m) => {
194 m.sign_bytes(secret, bytes) }
196 Self::BlockchainVerificationMethod2021(m) => {
197 m.sign_bytes(secret, algorithm.try_into()?, bytes)
198 }
199 #[cfg(all(feature = "eip712", feature = "secp256k1"))]
200 Self::Eip712Method2021(m) => {
201 SigningMethod::sign_bytes(m, secret, algorithm.try_into()?, bytes)
202 }
203 #[cfg(feature = "solana")]
204 Self::SolanaMethod2021(m) => {
205 m.sign_bytes(secret, Some(algorithm.try_into()?), bytes) }
207 m => Err(MessageSignatureError::UnsupportedVerificationMethod(
208 m.type_().name().to_owned(),
209 )),
210 }
211 }
212
213 fn sign_bytes_multi(
214 &self,
215 secret: &JWK,
216 algorithm: ssi_crypto::AlgorithmInstance,
217 messages: &[Vec<u8>],
218 ) -> Result<Vec<u8>, MessageSignatureError> {
219 match self {
220 Self::Multikey(m) => SigningMethod::<_, ssi_crypto::Algorithm>::sign_bytes_multi(
221 m, secret, algorithm, messages,
222 ),
223 m => Err(MessageSignatureError::UnsupportedVerificationMethod(
224 m.type_().name().to_owned(),
225 )),
226 }
227 }
228}
229
230ssi_verification_methods_core::verification_method_union! {
231 pub enum AnyJwkMethod, AnyJwkMethodType {
232 JsonWebKey2020,
234
235 #[cfg(feature = "rsa")]
237 RsaVerificationKey2018,
238
239 #[cfg(feature = "ed25519")]
241 Ed25519VerificationKey2018,
242
243 #[cfg(feature = "ed25519")]
245 Ed25519VerificationKey2020,
246
247 #[cfg(feature = "secp256k1")]
248 EcdsaSecp256k1VerificationKey2019,
249
250 #[cfg(feature = "secp256r1")]
251 EcdsaSecp256r1VerificationKey2019,
252
253 #[cfg(feature = "solana")]
254 SolanaMethod2021
255 }
256}
257
258impl AnyJwkMethod {
259 pub fn public_key_jwk(&self) -> Cow<JWK> {
263 match self {
264 Self::JsonWebKey2020(m) => Cow::Borrowed(m.public_key_jwk()),
265 #[cfg(feature = "rsa")]
266 Self::RsaVerificationKey2018(m) => Cow::Borrowed(m.public_key_jwk()),
267 #[cfg(feature = "ed25519")]
268 Self::Ed25519VerificationKey2018(m) => Cow::Owned(m.public_key_jwk()),
269 #[cfg(feature = "ed25519")]
270 Self::Ed25519VerificationKey2020(m) => Cow::Owned(m.public_key_jwk()),
271 #[cfg(feature = "secp256k1")]
272 Self::EcdsaSecp256k1VerificationKey2019(m) => m.public_key_jwk(),
273 #[cfg(feature = "secp256r1")]
274 Self::EcdsaSecp256r1VerificationKey2019(m) => Cow::Owned(m.public_key_jwk()),
275 #[cfg(feature = "solana")]
276 Self::SolanaMethod2021(m) => Cow::Borrowed(m.public_key_jwk()),
277 }
278 }
279}
280
281impl JwkVerificationMethod for AnyJwkMethod {
282 fn to_jwk(&self) -> Cow<JWK> {
283 self.public_key_jwk()
284 }
285}
286
287impl SigningMethod<JWK, ssi_crypto::Algorithm> for AnyJwkMethod {
288 fn sign_bytes(
289 &self,
290 secret: &JWK,
291 algorithm: ssi_crypto::AlgorithmInstance,
292 bytes: &[u8],
293 ) -> Result<Vec<u8>, MessageSignatureError> {
294 match self {
295 #[cfg(feature = "rsa")]
296 Self::RsaVerificationKey2018(m) => m.sign_bytes(bytes, secret),
297 #[cfg(feature = "ed25519")]
298 Self::Ed25519VerificationKey2018(m) => {
299 m.sign_bytes(secret, algorithm.try_into()?, bytes)
300 }
301 #[cfg(feature = "ed25519")]
302 Self::Ed25519VerificationKey2020(m) => match algorithm {
303 ssi_crypto::AlgorithmInstance::EdDSA => m.sign_bytes(secret, bytes),
304 _ => Err(MessageSignatureError::UnsupportedAlgorithm(
305 algorithm.algorithm().to_string(),
306 )),
307 },
308 #[cfg(feature = "secp256k1")]
309 Self::EcdsaSecp256k1VerificationKey2019(m) => match algorithm {
310 ssi_crypto::AlgorithmInstance::ES256K => m.sign_bytes(
311 secret,
312 ecdsa_secp_256k1_verification_key_2019::DigestFunction::Sha256,
313 bytes,
314 ),
315 _ => Err(MessageSignatureError::UnsupportedAlgorithm(
316 algorithm.algorithm().to_string(),
317 )),
318 },
319 #[cfg(feature = "secp256r1")]
320 Self::EcdsaSecp256r1VerificationKey2019(m) => match algorithm {
321 ssi_crypto::AlgorithmInstance::ES256 => m.sign_bytes(secret, bytes),
322 _ => Err(MessageSignatureError::UnsupportedAlgorithm(
323 algorithm.algorithm().to_string(),
324 )),
325 },
326 Self::JsonWebKey2020(m) => m.sign_bytes(secret, Some(algorithm.try_into()?), bytes),
327 #[cfg(feature = "solana")]
328 Self::SolanaMethod2021(m) => {
329 m.sign_bytes(secret, Some(algorithm.try_into()?), bytes) }
331 }
332 }
333}