ssi_data_integrity_core/suite/
configuration.rs1use std::marker::PhantomData;
2
3use ssi_claims_core::{ProofValidationError, SignatureError};
4use ssi_json_ld::syntax::Context;
5
6use crate::{CryptographicSuite, ProofConfiguration, ProofOptions};
7
8pub type InputVerificationMethod<S> = <<S as CryptographicSuite>::Configuration as ConfigurationAlgorithm<S>>::InputVerificationMethod;
9
10pub type InputSuiteOptions<S> =
11 <<S as CryptographicSuite>::Configuration as ConfigurationAlgorithm<S>>::InputSuiteOptions;
12
13pub type InputProofOptions<S> = ProofOptions<InputVerificationMethod<S>, InputSuiteOptions<S>>;
14
15pub type InputSignatureOptions<S> =
16 <<S as CryptographicSuite>::Configuration as ConfigurationAlgorithm<S>>::InputSignatureOptions;
17
18pub type InputVerificationOptions<S> =
19 <<S as CryptographicSuite>::Configuration as ConfigurationAlgorithm<S>>::InputVerificationOptions;
20
21pub type TransformationOptions<S> =
22 <<S as CryptographicSuite>::Configuration as ConfigurationAlgorithm<S>>::TransformationOptions;
23
24#[derive(Debug, thiserror::Error)]
25pub enum ConfigurationError {
26 #[error("missing verification method")]
27 MissingVerificationMethod,
28
29 #[error("missing option `{0}`")]
30 MissingOption(String),
31
32 #[error("invalid option `{0}`")]
33 InvalidOption(String),
34
35 #[error("{0}")]
36 Other(String),
37}
38
39impl From<std::convert::Infallible> for ConfigurationError {
40 fn from(_: std::convert::Infallible) -> Self {
41 unreachable!()
42 }
43}
44
45impl ConfigurationError {
46 pub fn invalid_option(e: impl ToString) -> Self {
47 Self::InvalidOption(e.to_string())
48 }
49
50 pub fn other(e: impl ToString) -> Self {
51 Self::Other(e.to_string())
52 }
53}
54
55impl From<ConfigurationError> for SignatureError {
56 fn from(value: ConfigurationError) -> Self {
57 Self::other(value)
58 }
59}
60
61impl From<ConfigurationError> for ProofValidationError {
62 fn from(value: ConfigurationError) -> Self {
63 Self::other(value)
64 }
65}
66
67pub trait ConfigurationAlgorithm<S: CryptographicSuite> {
68 type InputVerificationMethod;
70
71 type InputSuiteOptions;
75
76 type InputSignatureOptions;
80
81 type InputVerificationOptions;
85
86 type TransformationOptions;
88
89 fn configure_signature(
90 suite: &S,
91 proof_options: ProofOptions<Self::InputVerificationMethod, Self::InputSuiteOptions>,
92 signature_options: InputSignatureOptions<S>,
93 ) -> Result<(ProofConfiguration<S>, Self::TransformationOptions), ConfigurationError>;
94
95 fn configure_verification(
96 suite: &S,
97 verification_options: &InputVerificationOptions<S>,
98 ) -> Result<Self::TransformationOptions, ConfigurationError>;
99}
100
101pub struct NoConfiguration;
102
103impl<S: CryptographicSuite> ConfigurationAlgorithm<S> for NoConfiguration {
104 type InputVerificationMethod = S::VerificationMethod;
105 type InputSuiteOptions = S::ProofOptions;
106
107 type InputSignatureOptions = ();
108
109 type InputVerificationOptions = ();
110
111 type TransformationOptions = ();
112
113 fn configure_signature(
114 suite: &S,
115 proof_options: ProofOptions<S::VerificationMethod, S::ProofOptions>,
116 _: InputSignatureOptions<S>,
117 ) -> Result<(ProofConfiguration<S>, Self::TransformationOptions), ConfigurationError> {
118 Ok((proof_options.into_configuration(suite.clone())?, ()))
119 }
120
121 fn configure_verification(
122 _suite: &S,
123 _verification_options: &InputVerificationOptions<S>,
124 ) -> Result<Self::TransformationOptions, ConfigurationError> {
125 Ok(())
126 }
127}
128
129pub struct AddProofContext<C>(PhantomData<C>);
130
131impl<C, S: CryptographicSuite + Default> ConfigurationAlgorithm<S> for AddProofContext<C>
132where
133 C: Default + Into<ssi_json_ld::syntax::Context>,
134{
135 type InputVerificationMethod = S::VerificationMethod;
136 type InputSuiteOptions = S::ProofOptions;
137 type InputSignatureOptions = ();
138 type InputVerificationOptions = ();
139 type TransformationOptions = ();
140
141 fn configure_signature(
142 suite: &S,
143 options: ProofOptions<S::VerificationMethod, S::ProofOptions>,
144 _: InputSignatureOptions<S>,
145 ) -> Result<(ProofConfiguration<S>, Self::TransformationOptions), ConfigurationError> {
146 let mut result = options.into_configuration(suite.clone())?;
147 result.context = match result.context {
148 None => Some(C::default().into()),
149 Some(c) => Some(Context::Many(
150 c.into_iter().chain(C::default().into()).collect(),
151 )),
152 };
153 Ok((result, ()))
154 }
155
156 fn configure_verification(
157 _suite: &S,
158 _verification_options: &InputVerificationOptions<S>,
159 ) -> Result<Self::TransformationOptions, ConfigurationError> {
160 Ok(())
161 }
162}