1
+ use std:: str:: FromStr ;
2
+
1
3
use crate :: authorization_details:: AuthorizationDetailsObject ;
2
4
use crate :: authorization_request:: AuthorizationRequest ;
3
5
use crate :: authorization_response:: AuthorizationResponse ;
@@ -11,7 +13,7 @@ use crate::credential_request::{BatchCredentialRequest, CredentialRequest};
11
13
use crate :: credential_response:: BatchCredentialResponse ;
12
14
use crate :: proof:: { KeyProofType , ProofType } ;
13
15
use crate :: { credential_response:: CredentialResponse , token_request:: TokenRequest , token_response:: TokenResponse } ;
14
- use anyhow:: Result ;
16
+ use anyhow:: { anyhow , Result } ;
15
17
use jsonwebtoken:: Algorithm ;
16
18
use oid4vc_core:: authentication:: subject:: SigningSubject ;
17
19
use oid4vc_core:: SubjectSyntaxType ;
26
28
CFC : CredentialFormatCollection ,
27
29
{
28
30
pub subject : SigningSubject ,
29
- pub default_subject_syntax_type : SubjectSyntaxType ,
31
+ pub supported_subject_syntax_types : Vec < SubjectSyntaxType > ,
30
32
pub client : ClientWithMiddleware ,
31
33
pub proof_signing_alg_values_supported : Vec < Algorithm > ,
32
34
phantom : std:: marker:: PhantomData < CFC > ,
35
37
impl < CFC : CredentialFormatCollection + DeserializeOwned > Wallet < CFC > {
36
38
pub fn new (
37
39
subject : SigningSubject ,
38
- default_subject_syntax_type : impl TryInto < SubjectSyntaxType > ,
40
+ supported_subject_syntax_types : Vec < impl TryInto < SubjectSyntaxType > > ,
39
41
proof_signing_alg_values_supported : Vec < Algorithm > ,
40
42
) -> anyhow:: Result < Self > {
41
43
let retry_policy = ExponentialBackoff :: builder ( ) . build_with_max_retries ( 5 ) ;
@@ -44,9 +46,14 @@ impl<CFC: CredentialFormatCollection + DeserializeOwned> Wallet<CFC> {
44
46
. build ( ) ;
45
47
Ok ( Self {
46
48
subject,
47
- default_subject_syntax_type : default_subject_syntax_type
48
- . try_into ( )
49
- . map_err ( |_| anyhow:: anyhow!( "Invalid did method" ) ) ?,
49
+ supported_subject_syntax_types : supported_subject_syntax_types
50
+ . into_iter ( )
51
+ . map ( |subject_syntax_type| {
52
+ subject_syntax_type
53
+ . try_into ( )
54
+ . map_err ( |_| anyhow:: anyhow!( "Invalid did method." ) )
55
+ } )
56
+ . collect :: < Result < _ > > ( ) ?,
50
57
client,
51
58
proof_signing_alg_values_supported,
52
59
phantom : std:: marker:: PhantomData ,
@@ -121,7 +128,11 @@ impl<CFC: CredentialFormatCollection + DeserializeOwned> Wallet<CFC> {
121
128
client_id : self
122
129
. subject
123
130
. identifier (
124
- & self . default_subject_syntax_type . to_string ( ) ,
131
+ & self
132
+ . supported_subject_syntax_types
133
+ . first ( )
134
+ . map ( ToString :: to_string)
135
+ . ok_or ( anyhow ! ( "No supported subject syntax types found." ) ) ?,
125
136
self . proof_signing_alg_values_supported [ 0 ] ,
126
137
)
127
138
. await ?,
@@ -163,6 +174,22 @@ impl<CFC: CredentialFormatCollection + DeserializeOwned> Wallet<CFC> {
163
174
) ) ?
164
175
. proof_signing_alg_values_supported ;
165
176
177
+ let credential_issuer_cryptographic_binding_methods_supported: Vec < SubjectSyntaxType > =
178
+ credential_configuration
179
+ . cryptographic_binding_methods_supported
180
+ . iter ( )
181
+ . filter_map ( |binding_method| SubjectSyntaxType :: from_str ( binding_method) . ok ( ) )
182
+ . collect ( ) ;
183
+
184
+ let subject_syntax_type = self
185
+ . supported_subject_syntax_types
186
+ . iter ( )
187
+ . find ( |supported_syntax_type| {
188
+ credential_issuer_cryptographic_binding_methods_supported. contains ( supported_syntax_type)
189
+ } )
190
+ . or ( self . supported_subject_syntax_types . first ( ) )
191
+ . ok_or ( anyhow:: anyhow!( "No supported subject syntax types found." ) ) ?;
192
+
166
193
let signing_algorithm = self
167
194
. proof_signing_alg_values_supported
168
195
. iter ( )
@@ -179,10 +206,11 @@ impl<CFC: CredentialFormatCollection + DeserializeOwned> Wallet<CFC> {
179
206
. signer ( self . subject . clone ( ) )
180
207
. iss (
181
208
self . subject
182
- . identifier ( & self . default_subject_syntax_type . to_string ( ) , * signing_algorithm)
209
+ . identifier ( & subject_syntax_type . to_string ( ) , * signing_algorithm)
183
210
. await ?,
184
211
)
185
212
. aud ( credential_issuer_metadata. credential_issuer )
213
+ // TODO: Use current time.
186
214
. iat ( 1571324800 )
187
215
// TODO: so is this REQUIRED or OPTIONAL?
188
216
. nonce (
@@ -192,7 +220,7 @@ impl<CFC: CredentialFormatCollection + DeserializeOwned> Wallet<CFC> {
192
220
. ok_or ( anyhow:: anyhow!( "No c_nonce found." ) ) ?
193
221
. clone ( ) ,
194
222
)
195
- . subject_syntax_type ( self . default_subject_syntax_type . to_string ( ) )
223
+ . subject_syntax_type ( & subject_syntax_type . to_string ( ) )
196
224
. build ( )
197
225
. await ?,
198
226
) ,
@@ -226,6 +254,24 @@ impl<CFC: CredentialFormatCollection + DeserializeOwned> Wallet<CFC> {
226
254
) ) ?
227
255
. proof_signing_alg_values_supported ;
228
256
257
+ let credential_issuer_cryptographic_binding_methods_supported: Vec < SubjectSyntaxType > =
258
+ credential_configurations
259
+ . first ( )
260
+ . ok_or ( anyhow:: anyhow!( "No credential configurations found." ) ) ?
261
+ . cryptographic_binding_methods_supported
262
+ . iter ( )
263
+ . filter_map ( |binding_method| SubjectSyntaxType :: from_str ( binding_method) . ok ( ) )
264
+ . collect ( ) ;
265
+
266
+ let subject_syntax_type = self
267
+ . supported_subject_syntax_types
268
+ . iter ( )
269
+ . find ( |supported_syntax_type| {
270
+ credential_issuer_cryptographic_binding_methods_supported. contains ( supported_syntax_type)
271
+ } )
272
+ . or ( self . supported_subject_syntax_types . first ( ) )
273
+ . ok_or ( anyhow:: anyhow!( "No supported subject syntax types found." ) ) ?;
274
+
229
275
let signing_algorithm = self
230
276
. proof_signing_alg_values_supported
231
277
. iter ( )
@@ -241,10 +287,11 @@ impl<CFC: CredentialFormatCollection + DeserializeOwned> Wallet<CFC> {
241
287
. signer ( self . subject . clone ( ) )
242
288
. iss (
243
289
self . subject
244
- . identifier ( & self . default_subject_syntax_type . to_string ( ) , * signing_algorithm)
290
+ . identifier ( & subject_syntax_type . to_string ( ) , * signing_algorithm)
245
291
. await ?,
246
292
)
247
293
. aud ( credential_issuer_metadata. credential_issuer )
294
+ // TODO: Use current time.
248
295
. iat ( 1571324800 )
249
296
// TODO: so is this REQUIRED or OPTIONAL?
250
297
. nonce (
@@ -254,7 +301,7 @@ impl<CFC: CredentialFormatCollection + DeserializeOwned> Wallet<CFC> {
254
301
. ok_or ( anyhow:: anyhow!( "No c_nonce found." ) ) ?
255
302
. clone ( ) ,
256
303
)
257
- . subject_syntax_type ( self . default_subject_syntax_type . to_string ( ) )
304
+ . subject_syntax_type ( subject_syntax_type . to_string ( ) )
258
305
. build ( )
259
306
. await ?,
260
307
) ;
0 commit comments