diff --git a/auth/api/iam/openid4vp.go b/auth/api/iam/openid4vp.go index dfeb007d66..19908640ef 100644 --- a/auth/api/iam/openid4vp.go +++ b/auth/api/iam/openid4vp.go @@ -138,8 +138,8 @@ func (r *Wrapper) handlePresentationRequest(params map[string]string, session *S } submissionBuilder := presentationDefinition.PresentationSubmissionBuilder() - submissionBuilder.AddWallet(session.OwnDID, ownCredentials) - _, signInstructions, err := submissionBuilder.Build("ldp_vp") + submissionBuilder.AddWallet(session.OwnDID, ownCredentials, "ldp_vp") + _, signInstructions, err := submissionBuilder.Build() if err != nil { return nil, fmt.Errorf("unable to match presentation definition: %w", err) } @@ -210,8 +210,8 @@ func (r *Wrapper) handlePresentationRequestAccept(c echo.Context) error { // TODO: Options (including format) resultParams := map[string]string{} submissionBuilder := presentationDefinition.PresentationSubmissionBuilder() - submissionBuilder.AddWallet(session.OwnDID, credentials) - submission, signInstructions, err := submissionBuilder.Build("ldp_vp") + submissionBuilder.AddWallet(session.OwnDID, credentials, "ldp_vp") + submission, signInstructions, err := submissionBuilder.Build() if err != nil { return err } diff --git a/auth/services/oauth/relying_party.go b/auth/services/oauth/relying_party.go index 6960bf6d21..f65dfe7d1a 100644 --- a/auth/services/oauth/relying_party.go +++ b/auth/services/oauth/relying_party.go @@ -153,13 +153,13 @@ func (s *relyingParty) RequestRFC021AccessToken(ctx context.Context, requester d // if there's a match, create a VP and call the token endpoint // If the token endpoint succeeds, return the access token // If no presentation definition matches, return a 412 "no matching credentials" error - builder := presentationDefinition.PresentationSubmissionBuilder() - builder.AddWallet(requester, walletCredentials) format, err := determineFormat(metadata.VPFormats) if err != nil { return nil, err } - submission, signInstructions, err := builder.Build(format) + builder := presentationDefinition.PresentationSubmissionBuilder() + builder.AddWallet(requester, walletCredentials, format) + submission, signInstructions, err := builder.Build() if err != nil { return nil, fmt.Errorf("failed to match presentation definition: %w", err) } diff --git a/vcr/pe/presentation_submission.go b/vcr/pe/presentation_submission.go index 8dcef7c917..991b3b59a8 100644 --- a/vcr/pe/presentation_submission.go +++ b/vcr/pe/presentation_submission.go @@ -50,6 +50,7 @@ type PresentationSubmissionBuilder struct { holders []did.DID presentationDefinition PresentationDefinition wallets [][]vc.VerifiableCredential + presentationFormats []string } // PresentationSubmissionBuilder returns a new PresentationSubmissionBuilder. @@ -61,9 +62,11 @@ func (presentationDefinition PresentationDefinition) PresentationSubmissionBuild } // AddWallet adds credentials from a wallet that may be used to create the PresentationSubmission. -func (b *PresentationSubmissionBuilder) AddWallet(holder did.DID, vcs []vc.VerifiableCredential) *PresentationSubmissionBuilder { +// Presentation format indicates which VP format (ldp_vp or jwt_vp) will be used in the resulting submission and sign instructions. +func (b *PresentationSubmissionBuilder) AddWallet(holder did.DID, vcs []vc.VerifiableCredential, presentationFormat string) *PresentationSubmissionBuilder { b.holders = append(b.holders, holder) b.wallets = append(b.wallets, vcs) + b.presentationFormats = append(b.presentationFormats, presentationFormat) return b } @@ -76,6 +79,8 @@ type SignInstruction struct { VerifiableCredentials []vc.VerifiableCredential // Mappings contains the Input Descriptor that are mapped by this SignInstruction. Mappings []InputDescriptorMappingObject + // Format contains the proof format (ldp_vp, jwt_vp) that should be used for the resulting VP. + Format string } // Empty returns true if there are no VCs in the SignInstruction. @@ -97,8 +102,7 @@ func (signInstructions SignInstructions) Empty() bool { } // Build creates a PresentationSubmission from the added wallets. -// The VP format is determined by the given format. -func (b *PresentationSubmissionBuilder) Build(format string) (PresentationSubmission, SignInstructions, error) { +func (b *PresentationSubmissionBuilder) Build() (PresentationSubmission, SignInstructions, error) { presentationSubmission := PresentationSubmission{ Id: uuid.New().String(), DefinitionId: b.presentationDefinition.Id, @@ -125,6 +129,7 @@ func (b *PresentationSubmissionBuilder) Build(format string) (PresentationSubmis // do a JSON equality check if selectedVCs[j].Raw() == walletVC.Raw() { signInstructions[i].Holder = b.holders[i] + signInstructions[i].Format = b.presentationFormats[i] signInstructions[i].VerifiableCredentials = append(signInstructions[i].VerifiableCredentials, selectedVCs[j]) // remap the path to the correct wallet index mapping := inputDescriptorMappingObjects[j] @@ -156,7 +161,7 @@ func (b *PresentationSubmissionBuilder) Build(format string) (PresentationSubmis if len(nonEmptySignInstructions) > 1 { presentationSubmission.DescriptorMap = append(presentationSubmission.DescriptorMap, InputDescriptorMappingObject{ Id: inputDescriptorMapping.Id, - Format: format, + Format: signInstruction.Format, Path: fmt.Sprintf("$[%d]", index), PathNested: &inputDescriptorMapping, }) diff --git a/vcr/pe/presentation_submission_test.go b/vcr/pe/presentation_submission_test.go index 4acbc873b3..3f4acb9352 100644 --- a/vcr/pe/presentation_submission_test.go +++ b/vcr/pe/presentation_submission_test.go @@ -73,9 +73,9 @@ func TestPresentationSubmissionBuilder_Build(t *testing.T) { presentationDefinition := PresentationDefinition{} _ = json.Unmarshal([]byte(test.All), &presentationDefinition) builder := presentationDefinition.PresentationSubmissionBuilder() - builder.AddWallet(holder1, []vc.VerifiableCredential{vc1, vc2}) + builder.AddWallet(holder1, []vc.VerifiableCredential{vc1, vc2}, "ldp_vc") - submission, signInstructions, err := builder.Build("ldp_vp") + submission, signInstructions, err := builder.Build() require.NoError(t, err) require.NotNil(t, signInstructions) @@ -104,7 +104,7 @@ func TestPresentationSubmissionBuilder_Build(t *testing.T) { } }, { - "format": "ldp_vp", + "format": "jwt_vp", "id": "Match ID=2", "path": "$[1]", "path_nested": { @@ -119,14 +119,18 @@ func TestPresentationSubmissionBuilder_Build(t *testing.T) { presentationDefinition := PresentationDefinition{} _ = json.Unmarshal([]byte(test.All), &presentationDefinition) builder := presentationDefinition.PresentationSubmissionBuilder() - builder.AddWallet(holder1, []vc.VerifiableCredential{vc1}) - builder.AddWallet(holder2, []vc.VerifiableCredential{vc2}) + builder.AddWallet(holder1, []vc.VerifiableCredential{vc1}, "ldp_vp") + builder.AddWallet(holder2, []vc.VerifiableCredential{vc2}, "jwt_vp") - submission, signInstructions, err := builder.Build("ldp_vp") + submission, signInstructions, err := builder.Build() require.NoError(t, err) require.NotNil(t, signInstructions) assert.Len(t, signInstructions, 2) + assert.Equal(t, holder1, signInstructions[0].Holder) + assert.Equal(t, "ldp_vp", signInstructions[0].Format) + assert.Equal(t, holder2, signInstructions[1].Holder) + assert.Equal(t, "jwt_vp", signInstructions[1].Format) assert.Len(t, submission.DescriptorMap, 2) submission.Id = "for-test" // easier assertion @@ -154,10 +158,10 @@ func TestPresentationSubmissionBuilder_Build(t *testing.T) { presentationDefinition := PresentationDefinition{} _ = json.Unmarshal([]byte(test.All), &presentationDefinition) builder := presentationDefinition.PresentationSubmissionBuilder() - builder.AddWallet(holder1, []vc.VerifiableCredential{vc1, vc2}) - builder.AddWallet(holder2, []vc.VerifiableCredential{vc3}) + builder.AddWallet(holder1, []vc.VerifiableCredential{vc1, vc2}, "ldp_vp") + builder.AddWallet(holder2, []vc.VerifiableCredential{vc3}, "jwt_vp") - submission, signInstructions, err := builder.Build("ldp_vp") + submission, signInstructions, err := builder.Build() require.NoError(t, err) require.NotNil(t, signInstructions)