Skip to content

Commit

Permalink
feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
reinkrul committed Nov 18, 2023
1 parent 8de1e41 commit 12fe196
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 75 deletions.
26 changes: 26 additions & 0 deletions vcr/credential/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,14 @@
package credential

import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"encoding/json"
"github.com/lestrrat-go/jwx/v2/jwa"
"github.com/lestrrat-go/jwx/v2/jwt"
"github.com/nuts-foundation/nuts-node/vcr/assets"
"github.com/stretchr/testify/require"
"testing"
"time"

Expand Down Expand Up @@ -68,6 +74,26 @@ func ValidNutsOrganizationCredential(t *testing.T) vc.VerifiableCredential {
return inputVC
}

func JWTNutsOrganizationCredential(t *testing.T) vc.VerifiableCredential {
privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
require.NoError(t, err)
token := jwt.New()
require.NoError(t, token.Set("vc", map[string]interface{}{
"credentialSubject": map[string]interface{}{
"organization": map[string]interface{}{
"city": "IJbergen",
"name": "care",
},
},
"type": "NutsOrganizationCredential",
}))
signedToken, err := jwt.Sign(token, jwt.WithKey(jwa.ES384, privateKey))
require.NoError(t, err)
jwtVC, err := vc.ParseVerifiableCredential(string(signedToken))
require.NoError(t, err)
return *jwtVC
}

func stringToURI(input string) ssi.URI {
return ssi.MustParseURI(input)
}
8 changes: 4 additions & 4 deletions vcr/pe/presentation_definition.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ func matchFormat(format *PresentationDefinitionClaimFormatDesignations, credenti
asMap := map[string]map[string][]string(*format)
switch credential.Format() {
case vc.JSONLDCredentialProofFormat:
if entry := asMap["ldp_vc"]; entry != nil {
if entry := asMap[vc.JSONLDCredentialProofFormat]; entry != nil {
if proofTypes := entry["proof_type"]; proofTypes != nil {
for _, proofType := range proofTypes {
if matchProofType(proofType, credential) {
Expand All @@ -245,10 +245,10 @@ func matchFormat(format *PresentationDefinitionClaimFormatDesignations, credenti
case vc.JWTCredentialProofFormat:
// Get signing algorithm used to sign the JWT
message, _ := jws.ParseString(credential.Raw()) // can't really fail, JWT has been parsed before.
signingAlgorithm, _ := message.Signatures()[0].ProtectedHeaders().Get("alg")
signingAlgorithm, _ := message.Signatures()[0].ProtectedHeaders().Get(jws.AlgorithmKey)
// Check that the signing algorithm is specified by the presentation definition
if entry := asMap["jwt_vc"]; entry != nil {
if supportedAlgorithms := entry["alg"]; supportedAlgorithms != nil {
if entry := asMap[vc.JWTCredentialProofFormat]; entry != nil {
if supportedAlgorithms := entry[jws.AlgorithmKey]; supportedAlgorithms != nil {
for _, supportedAlgorithm := range supportedAlgorithms {
if signingAlgorithm == jwa.SignatureAlgorithm(supportedAlgorithm) {
return true
Expand Down
53 changes: 30 additions & 23 deletions vcr/pe/presentation_definition_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ var testFiles embed.FS

var pdJSONLD PresentationDefinition
var pdJSONLDorJWT PresentationDefinition
var pdJSONLDorJWTWithPick PresentationDefinition
var pdJWT PresentationDefinition

func init() {
Expand All @@ -66,6 +67,13 @@ func init() {
panic(err)
}
}
if data, err := testFiles.ReadFile("test/pd_jsonld_jwt_pick.json"); err != nil {
panic(err)
} else {
if err = json.Unmarshal(data, &pdJSONLDorJWTWithPick); err != nil {
panic(err)
}
}
if data, err := testFiles.ReadFile("test/pd_jwt.json"); err != nil {
panic(err)
} else {
Expand All @@ -76,26 +84,8 @@ func init() {
}

func TestMatch(t *testing.T) {
// Create a JSON-LD VC
jsonldVC := credential.ValidNutsOrganizationCredential(t)

// Create a JWT VC
privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
require.NoError(t, err)
token := jwt.New()
require.NoError(t, token.Set("vc", map[string]interface{}{
"credentialSubject": map[string]interface{}{
"organization": map[string]interface{}{
"city": "IJbergen",
"name": "care",
},
},
"type": "NutsOrganizationCredential",
}))
signedToken, err := jwt.Sign(token, jwt.WithKey(jwa.ES384, privateKey))
require.NoError(t, err)
jwtVC, err := vc.ParseVerifiableCredential(string(signedToken))
require.NoError(t, err)
jwtVC := credential.JWTNutsOrganizationCredential(t)

t.Run("Basic", func(t *testing.T) {
t.Run("JSON-LD", func(t *testing.T) {
Expand All @@ -117,13 +107,15 @@ func TestMatch(t *testing.T) {
})
t.Run("JWT", func(t *testing.T) {
t.Run("Happy flow", func(t *testing.T) {
vcs, mappingObjects, err := pdJWT.Match([]vc.VerifiableCredential{*jwtVC})
vcs, mappingObjects, err := pdJWT.Match([]vc.VerifiableCredential{jwtVC})
require.NoError(t, err)
assert.Len(t, vcs, 1)
require.Len(t, mappingObjects, 1)
assert.Equal(t, "$.verifiableCredential[0]", mappingObjects[0].Path)
})
t.Run("unsupported JOSE alg", func(t *testing.T) {
token := jwt.New()
privateKey, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
signedToken, err := jwt.Sign(token, jwt.WithKey(jwa.ES256, privateKey))
require.NoError(t, err)
jwtCredential, err := vc.ParseVerifiableCredential(string(signedToken))
Expand Down Expand Up @@ -158,15 +150,29 @@ func TestMatch(t *testing.T) {
assert.Len(t, vcs, 1)
assert.Len(t, mappingObjects, 1)
})
t.Run("pick JSON-LD", func(t *testing.T) {
t.Run("choose JSON-LD (with multiple 'path's)", func(t *testing.T) {
vcs, mappingObjects, err := pdJSONLDorJWT.Match([]vc.VerifiableCredential{jsonldVC})

require.NoError(t, err)
assert.Len(t, vcs, 1)
require.Len(t, mappingObjects, 1)
})
t.Run("pick JWT", func(t *testing.T) {
vcs, mappingObjects, err := pdJSONLDorJWT.Match([]vc.VerifiableCredential{*jwtVC})
t.Run("choose JWT(with multiple 'path's)", func(t *testing.T) {
vcs, mappingObjects, err := pdJSONLDorJWT.Match([]vc.VerifiableCredential{jwtVC})

require.NoError(t, err)
assert.Len(t, vcs, 1)
require.Len(t, mappingObjects, 1)
})
t.Run("choose JSON-LD (with 'pick')", func(t *testing.T) {
vcs, mappingObjects, err := pdJSONLDorJWTWithPick.Match([]vc.VerifiableCredential{jsonldVC})

require.NoError(t, err)
assert.Len(t, vcs, 1)
require.Len(t, mappingObjects, 1)
})
t.Run("choose JWT (with 'pick')", func(t *testing.T) {
vcs, mappingObjects, err := pdJSONLDorJWTWithPick.Match([]vc.VerifiableCredential{jwtVC})

require.NoError(t, err)
assert.Len(t, vcs, 1)
Expand Down Expand Up @@ -320,6 +326,7 @@ func Test_matchFormat(t *testing.T) {
})

t.Run("JWT", func(t *testing.T) {
// JWT example credential taken from VC data model (expired)
const jwtCredential = `eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImRpZDpleGFtcGxlOmFiZmUxM2Y3MTIxMjA0
MzFjMjc2ZTEyZWNhYiNrZXlzLTEifQ.eyJzdWIiOiJkaWQ6ZXhhbXBsZTplYmZlYjFmNzEyZWJjNmYxY
zI3NmUxMmVjMjEiLCJqdGkiOiJodHRwOi8vZXhhbXBsZS5lZHUvY3JlZGVudGlhbHMvMzczMiIsImlzc
Expand Down
50 changes: 2 additions & 48 deletions vcr/pe/test/pd_jsonld_jwt.json
Original file line number Diff line number Diff line change
@@ -1,59 +1,12 @@
{
"id": "Definition requesting NutsOrganizationCredential",
"submission_requirements": [
{
"rule": "pick",
"count": 1,
"from": "vc"
}
],
"input_descriptors": [
{
"id": "as_jsonld",
"group": [
"vc"
],
"constraints": {
"fields": [
{
"path": [
"$.credentialSubject.organization.city"
],
"filter": {
"type": "string",
"const": "IJbergen"
}
},
{
"path": [
"$.credentialSubject.organization.name"
],
"filter": {
"type": "string",
"pattern": "care"
}
},
{
"path": [
"$.type"
],
"filter": {
"type": "string",
"const": "NutsOrganizationCredential"
}
}
]
}
},
{
"id": "as_jwt",
"group": [
"vc"
],
"constraints": {
"fields": [
{
"path": [
"$.credentialSubject.organization.city",
"$.credentialSubject[0].organization.city"
],
"filter": {
Expand All @@ -63,6 +16,7 @@
},
{
"path": [
"$.credentialSubject.organization.name",
"$.credentialSubject[0].organization.name"
],
"filter": {
Expand Down
99 changes: 99 additions & 0 deletions vcr/pe/test/pd_jsonld_jwt_pick.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
{
"id": "Definition requesting NutsOrganizationCredential",
"submission_requirements": [
{
"rule": "pick",
"count": 1,
"from": "vc"
}
],
"input_descriptors": [
{
"id": "as_jsonld",
"group": [
"vc"
],
"constraints": {
"fields": [
{
"path": [
"$.credentialSubject.organization.city"
],
"filter": {
"type": "string",
"const": "IJbergen"
}
},
{
"path": [
"$.credentialSubject.organization.name"
],
"filter": {
"type": "string",
"pattern": "care"
}
},
{
"path": [
"$.type"
],
"filter": {
"type": "string",
"const": "NutsOrganizationCredential"
}
}
]
}
},
{
"id": "as_jwt",
"group": [
"vc"
],
"constraints": {
"fields": [
{
"path": [
"$.credentialSubject[0].organization.city"
],
"filter": {
"type": "string",
"const": "IJbergen"
}
},
{
"path": [
"$.credentialSubject[0].organization.name"
],
"filter": {
"type": "string",
"pattern": "care"
}
},
{
"path": [
"$.type"
],
"filter": {
"type": "string",
"const": "NutsOrganizationCredential"
}
}
]
}
}
],
"format": {
"jwt_vc": {
"alg": [
"ES256K",
"ES384"
]
},
"ldp_vc": {
"proof_type": [
"JsonWebSignature2020"
]
}
}
}

0 comments on commit 12fe196

Please sign in to comment.