@@ -27,6 +27,7 @@ import (
2727)
2828
2929const (
30+
3031 // All rule`s value.
3132 All Selection = "all"
3233 // Pick rule`s value.
@@ -38,6 +39,8 @@ const (
3839 Preferred Preference = "preferred"
3940
4041 tmpEnding = "tmp_unique_id_"
42+
43+ credentialSchema = "credentialSchema"
4144)
4245
4346var errPathNotApplicable = errors .New ("path not applicable" )
@@ -93,6 +96,8 @@ type PresentationDefinition struct {
9396 // Format is an object with one or more properties matching the registered Claim Format Designations
9497 // (jwt, jwt_vc, jwt_vp, etc.) to inform the Holder of the claim format configurations the Verifier can process.
9598 Format * Format `json:"format,omitempty"`
99+ // Frame is used for JSON-LD document framing.
100+ Frame map [string ]interface {} `json:"frame,omitempty"`
96101 // SubmissionRequirements must conform to the Submission Requirement Format.
97102 // If not present, all inputs listed in the InputDescriptors array are required for submission.
98103 SubmissionRequirements []* SubmissionRequirement `json:"submission_requirements,omitempty"`
@@ -121,6 +126,7 @@ type InputDescriptor struct {
121126 Metadata map [string ]interface {} `json:"metadata,omitempty"`
122127 Schema []* Schema `json:"schema,omitempty"`
123128 Constraints * Constraints `json:"constraints,omitempty"`
129+ Format * Format `json:"format,omitempty"`
124130}
125131
126132// Schema input descriptor schema.
@@ -145,11 +151,12 @@ type Constraints struct {
145151
146152// Field describes Constraints`s Fields field.
147153type Field struct {
148- Path []string `json:"path,omitempty"`
149- ID string `json:"id,omitempty"`
150- Purpose string `json:"purpose,omitempty"`
151- Filter * Filter `json:"filter,omitempty"`
152- Predicate * Preference `json:"predicate,omitempty"`
154+ Path []string `json:"path,omitempty"`
155+ ID string `json:"id,omitempty"`
156+ Purpose string `json:"purpose,omitempty"`
157+ Filter * Filter `json:"filter,omitempty"`
158+ Predicate * Preference `json:"predicate,omitempty"`
159+ IntentToRetain bool `json:"intent_to_retain,omitempty"`
153160}
154161
155162// Filter describes filter.
@@ -171,11 +178,21 @@ type Filter struct {
171178// ValidateSchema validates presentation definition.
172179func (pd * PresentationDefinition ) ValidateSchema () error {
173180 result , err := gojsonschema .Validate (
174- gojsonschema .NewStringLoader (DefinitionJSONSchema ),
181+ gojsonschema .NewStringLoader (DefinitionJSONSchemaV1 ),
175182 gojsonschema .NewGoLoader (struct {
176183 PD * PresentationDefinition `json:"presentation_definition"`
177184 }{PD : pd }),
178185 )
186+
187+ if err != nil || ! result .Valid () {
188+ result , err = gojsonschema .Validate (
189+ gojsonschema .NewStringLoader (DefinitionJSONSchemaV2 ),
190+ gojsonschema .NewGoLoader (struct {
191+ PD * PresentationDefinition `json:"presentation_definition"`
192+ }{PD : pd }),
193+ )
194+ }
195+
179196 if err != nil {
180197 return err
181198 }
@@ -310,7 +327,7 @@ func (pd *PresentationDefinition) CreateVP(credentials []*verifiable.Credential,
310327 return nil , err
311328 }
312329
313- result , err := applyRequirement (req , credentials , documentLoader , opts ... )
330+ result , err := pd . applyRequirement (req , credentials , documentLoader , opts ... )
314331 if err != nil {
315332 return nil , err
316333 }
@@ -340,14 +357,33 @@ func (pd *PresentationDefinition) CreateVP(credentials []*verifiable.Credential,
340357var ErrNoCredentials = errors .New ("credentials do not satisfy requirements" )
341358
342359// nolint: gocyclo,funlen,gocognit
343- func applyRequirement (req * requirement , creds []* verifiable.Credential ,
360+ func ( pd * PresentationDefinition ) applyRequirement (req * requirement , creds []* verifiable.Credential ,
344361 documentLoader ld.DocumentLoader , opts ... verifiable.CredentialOpt ) (map [string ][]* verifiable.Credential , error ) {
345362 result := make (map [string ][]* verifiable.Credential )
346363
347364 for _ , descriptor := range req .InputDescriptors {
348- filtered := filterSchema (descriptor .Schema , creds , documentLoader )
365+ format := pd .Format
366+ if descriptor .Format != nil {
367+ format = descriptor .Format
368+ }
369+
370+ filtered := creds
371+
372+ filtered , err := frameCreds (pd .Frame , filtered , opts ... )
373+ if err != nil {
374+ return nil , err
375+ }
376+
377+ if format != nil {
378+ filtered = filterFormat (format , filtered )
379+ }
380+
381+ // Validate schema only for v1
382+ if descriptor .Schema != nil {
383+ filtered = filterSchema (descriptor .Schema , filtered , documentLoader )
384+ }
349385
350- filtered , err : = filterConstraints (descriptor .Constraints , filtered , opts ... )
386+ filtered , err = filterConstraints (descriptor .Constraints , filtered , opts ... )
351387 if err != nil {
352388 return nil , err
353389 }
@@ -371,7 +407,7 @@ func applyRequirement(req *requirement, creds []*verifiable.Credential,
371407 set := map [string ]map [string ]string {}
372408
373409 for _ , r := range req .Nested {
374- res , err := applyRequirement (r , creds , documentLoader , opts ... )
410+ res , err := pd . applyRequirement (r , creds , documentLoader , opts ... )
375411 if errors .Is (err , ErrNoCredentials ) {
376412 continue
377413 }
@@ -594,10 +630,30 @@ func filterConstraints(constraints *Constraints, creds []*verifiable.Credential,
594630 return result , nil
595631}
596632
633+ func frameCreds (frame map [string ]interface {}, creds []* verifiable.Credential ,
634+ opts ... verifiable.CredentialOpt ) ([]* verifiable.Credential , error ) {
635+ if frame == nil {
636+ return creds , nil
637+ }
638+
639+ var result []* verifiable.Credential
640+
641+ for _ , credential := range creds {
642+ bbsVC , err := credential .GenerateBBSSelectiveDisclosure (frame , nil , opts ... )
643+ if err != nil {
644+ return nil , err
645+ }
646+
647+ result = append (result , bbsVC )
648+ }
649+
650+ return result , nil
651+ }
652+
597653func toSubject (subject interface {}) interface {} {
598654 sub , ok := subject .([]verifiable.Subject )
599655 if ok && len (sub ) == 1 {
600- return sub [0 ]
656+ return verifiable. Subject { ID : sub [0 ]. ID }
601657 }
602658
603659 return subject
@@ -650,6 +706,10 @@ func createNewCredential(constraints *Constraints, src, limitedCred []byte,
650706 }
651707
652708 for _ , path := range jPaths {
709+ if strings .Contains (path [0 ], credentialSchema ) {
710+ continue
711+ }
712+
653713 var val interface {} = true
654714
655715 if ! modifiedByPredicate {
@@ -772,26 +832,40 @@ func hasBBS(vc *verifiable.Credential) bool {
772832 return false
773833}
774834
835+ func hasProofWithType (vc * verifiable.Credential , proofType string ) bool {
836+ for _ , proof := range vc .Proofs {
837+ if proof ["type" ] == proofType {
838+ return true
839+ }
840+ }
841+
842+ return false
843+ }
844+
775845func filterField (f * Field , credential map [string ]interface {}) error {
776846 var schema gojsonschema.JSONLoader
777847
778848 if f .Filter != nil {
779849 schema = gojsonschema .NewGoLoader (* f .Filter )
780850 }
781851
852+ var lastErr error
853+
782854 for _ , path := range f .Path {
783855 patch , err := jsonpath .Get (path , credential )
784- if err != nil {
785- return errPathNotApplicable
786- }
856+ if err == nil {
857+ err = validatePatch (schema , patch )
858+ if err == nil {
859+ return nil
860+ }
787861
788- err = validatePatch ( schema , patch )
789- if err != nil {
790- return err
862+ lastErr = err
863+ } else {
864+ lastErr = errPathNotApplicable
791865 }
792866 }
793867
794- return nil
868+ return lastErr
795869}
796870
797871func validatePatch (schema gojsonschema.JSONLoader , patch interface {}) error {
@@ -888,6 +962,24 @@ func (a byID) Len() int { return len(a) }
888962func (a byID ) Less (i , j int ) bool { return a [i ].ID < a [j ].ID }
889963func (a byID ) Swap (i , j int ) { a [i ], a [j ] = a [j ], a [i ] }
890964
965+ func filterFormat (format * Format , credentials []* verifiable.Credential ) []* verifiable.Credential {
966+ var result []* verifiable.Credential
967+
968+ if format .LdpVP == nil {
969+ return result
970+ }
971+
972+ for _ , credential := range credentials {
973+ for _ , proofType := range format .LdpVP .ProofType {
974+ if hasProofWithType (credential , proofType ) {
975+ result = append (result , credential )
976+ }
977+ }
978+ }
979+
980+ return result
981+ }
982+
891983// nolint: gocyclo
892984func filterSchema (schemas []* Schema , credentials []* verifiable.Credential ,
893985 documentLoader ld.DocumentLoader ) []* verifiable.Credential {
0 commit comments