ssi_data_integrity/any/suite/
pick.rs

1use ssi_jwk::JWK;
2use ssi_verification_methods::{AnyMethod, ReferenceOrOwned};
3
4use crate::AnySuite;
5
6impl AnySuite {
7    #[allow(unused)]
8    pub fn pick(
9        jwk: &JWK,
10        verification_method: Option<&ReferenceOrOwned<AnyMethod>>,
11    ) -> Option<Self> {
12        if let Some(vm) = verification_method {
13            #[cfg(feature = "w3c")]
14            if vm.id().starts_with("did:jwk:") {
15                return Some(Self::JsonWebSignature2020);
16            }
17        }
18
19        use ssi_jwk::Algorithm;
20        let algorithm = jwk.get_algorithm()?;
21        match algorithm {
22            #[cfg(all(feature = "w3c", feature = "rsa"))]
23            Algorithm::RS256 => Some(Self::RsaSignature2018),
24            #[cfg(feature = "w3c")]
25            Algorithm::PS256 => Some(Self::JsonWebSignature2020),
26            #[cfg(feature = "w3c")]
27            Algorithm::ES384 => Some(Self::JsonWebSignature2020),
28            #[cfg(feature = "aleo")]
29            Algorithm::AleoTestnet1Signature => Some(Self::AleoSignature2021),
30            Algorithm::EdDSA | Algorithm::EdBlake2b => match verification_method {
31                #[cfg(feature = "solana")]
32                Some(vm)
33                    if (vm.id().starts_with("did:sol:") || vm.id().starts_with("did:pkh:sol:"))
34                        && vm.id().ends_with("#SolanaMethod2021") =>
35                {
36                    Some(Self::SolanaSignature2021)
37                }
38                #[cfg(feature = "tezos")]
39                Some(vm)
40                    if vm.id().starts_with("did:tz:") || vm.id().starts_with("did:pkh:tz:") =>
41                {
42                    if vm.id().ends_with("#TezosMethod2021") {
43                        return Some(Self::TezosSignature2021);
44                    }
45
46                    #[cfg(feature = "ed25519")]
47                    return Some(Self::Ed25519BLAKE2BDigestSize20Base58CheckEncodedSignature2021);
48
49                    None
50                }
51                #[cfg(all(feature = "w3c", feature = "ed25519"))]
52                _ => Some(Self::Ed25519Signature2018),
53                #[cfg(not(all(feature = "w3c", feature = "ed25519")))]
54                _ => {
55                    // missing `ed25519` or `tezos` or `solana`.
56                    None
57                }
58            },
59            Algorithm::ES256 | Algorithm::ESBlake2b => match verification_method {
60                #[cfg(feature = "tezos")]
61                Some(vm)
62                    if vm.id().starts_with("did:tz:") || vm.id().starts_with("did:pkh:tz:") =>
63                {
64                    if vm.id().ends_with("#TezosMethod2021") {
65                        return Some(Self::TezosSignature2021);
66                    }
67
68                    #[cfg(feature = "secp256r1")]
69                    return Some(Self::P256BLAKE2BDigestSize20Base58CheckEncodedSignature2021);
70
71                    None
72                }
73                #[cfg(all(feature = "w3c", feature = "secp256r1"))]
74                _ => Some(Self::EcdsaSecp256r1Signature2019),
75                #[allow(unreachable_patterns)]
76                _ => {
77                    // missing `secp256r1` or `tezos` features.
78                    None
79                }
80            },
81            Algorithm::ES256K | Algorithm::ESBlake2bK => match verification_method {
82                #[cfg(any(feature = "tezos", feature = "dif"))]
83                #[allow(unreachable_code)]
84                Some(vm)
85                    if vm.id().starts_with("did:tz:") || vm.id().starts_with("did:pkh:tz:") =>
86                {
87                    #[cfg(feature = "tezos")]
88                    if vm.id().ends_with("#TezosMethod2021") {
89                        return Some(Self::TezosSignature2021);
90                    }
91
92                    #[cfg(all(feature = "dif", feature = "secp256k1"))]
93                    return Some(Self::EcdsaSecp256k1RecoverySignature2020);
94
95                    None
96                }
97                #[cfg(all(feature = "w3c", feature = "secp256k1"))]
98                _ => Some(Self::EcdsaSecp256k1Signature2019),
99                #[allow(unreachable_patterns)]
100                _ => None,
101            },
102            Algorithm::ES256KR => {
103                // #[allow(clippy::if_same_then_else)]
104                #[cfg(all(feature = "w3c", feature = "eip712"))]
105                if use_eip712sig(jwk) {
106                    return Some(Self::EthereumEip712Signature2021);
107                }
108                #[cfg(all(feature = "ethereum", feature = "secp256k1"))]
109                if use_epsig(jwk) {
110                    return Some(Self::EthereumPersonalSignature2021);
111                }
112
113                match verification_method {
114                    #[cfg(all(feature = "ethereum", feature = "eip712"))]
115                    Some(vm)
116                        if (vm.id().starts_with("did:ethr:")
117                            || vm.id().starts_with("did:pkh:eth:"))
118                            && vm.id().ends_with("#Eip712Method2021") =>
119                    {
120                        Some(Self::Eip712Signature2021)
121                    }
122
123                    #[cfg(all(feature = "dif", feature = "secp256k1"))]
124                    _ => Some(Self::EcdsaSecp256k1RecoverySignature2020),
125                    #[allow(unreachable_patterns)]
126                    _ => None,
127                }
128            }
129            _ => None,
130        }
131    }
132}
133
134#[cfg(all(feature = "w3c", feature = "eip712"))]
135fn use_eip712sig(key: &JWK) -> bool {
136    // deprecated: allow using unregistered "signTypedData" key operation value to indicate using EthereumEip712Signature2021
137    if let Some(ref key_ops) = key.key_operations {
138        if key_ops.contains(&"signTypedData".to_string()) {
139            return true;
140        }
141    }
142    false
143}
144
145#[cfg(all(feature = "ethereum", feature = "secp256k1"))]
146fn use_epsig(key: &JWK) -> bool {
147    // deprecated: allow using unregistered "signPersonalMessage" key operation value to indicate using EthereumPersonalSignature2021
148    if let Some(ref key_ops) = key.key_operations {
149        if key_ops.contains(&"signPersonalMessage".to_string()) {
150            return true;
151        }
152    }
153    false
154}