Skip to content
This repository has been archived by the owner on Mar 27, 2024. It is now read-only.

Commit

Permalink
test: jwt format tests in presentation exchange (#3364)
Browse files Browse the repository at this point in the history
includes unit and bdd tests + decoding jwt VC in presentation's decodeCredentials()

closes #3327

Signed-off-by: Baha Shaaban <[email protected]>

Signed-off-by: Baha Shaaban <[email protected]>
  • Loading branch information
baha-ai authored Sep 11, 2022
1 parent f91d623 commit 9fc7486
Show file tree
Hide file tree
Showing 7 changed files with 521 additions and 191 deletions.
11 changes: 10 additions & 1 deletion pkg/doc/presexch/definition.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/xeipuuv/gojsonschema"

"github.com/hyperledger/aries-framework-go/pkg/common/log"
"github.com/hyperledger/aries-framework-go/pkg/doc/jose"
"github.com/hyperledger/aries-framework-go/pkg/doc/jwt"
"github.com/hyperledger/aries-framework-go/pkg/doc/verifiable"
)
Expand Down Expand Up @@ -1012,7 +1013,7 @@ func filterFormat(format *Format, credentials []*verifiable.Credential) (string,
)

if credential.JWT != "" {
pJWT, err := jwt.Parse(credential.JWT)
pJWT, err := jwt.Parse(credential.JWT, jwt.WithSignatureVerifier(&noVerifier{}))
if err != nil {
logger.Warnf("unmarshal credential error: %w", err)

Expand Down Expand Up @@ -1062,6 +1063,14 @@ func filterFormat(format *Format, credentials []*verifiable.Credential) (string,
return "", nil
}

// noVerifier is used when no JWT signature verification is needed.
// To be used with precaution.
type noVerifier struct{}

func (v noVerifier) Verify(_ jose.Headers, _, _, _ []byte) error {
return nil
}

func algMatch(credAlg string, jwtType *JwtType) bool {
if jwtType == nil {
return false
Expand Down
165 changes: 124 additions & 41 deletions pkg/doc/presexch/definition_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,21 @@ import (
"github.com/stretchr/testify/require"

"github.com/hyperledger/aries-framework-go/pkg/crypto/primitive/bbs12381g2pub"
"github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto"
"github.com/hyperledger/aries-framework-go/pkg/doc/ld"
. "github.com/hyperledger/aries-framework-go/pkg/doc/presexch"
"github.com/hyperledger/aries-framework-go/pkg/doc/signature/jsonld"
"github.com/hyperledger/aries-framework-go/pkg/doc/signature/suite"
"github.com/hyperledger/aries-framework-go/pkg/doc/signature/suite/bbsblssignature2020"
"github.com/hyperledger/aries-framework-go/pkg/doc/util"
"github.com/hyperledger/aries-framework-go/pkg/doc/util/signature"
"github.com/hyperledger/aries-framework-go/pkg/doc/verifiable"
"github.com/hyperledger/aries-framework-go/pkg/internal/ldtestutil"
"github.com/hyperledger/aries-framework-go/pkg/kms"
"github.com/hyperledger/aries-framework-go/pkg/kms/localkms"
mockkms "github.com/hyperledger/aries-framework-go/pkg/mock/kms"
"github.com/hyperledger/aries-framework-go/pkg/mock/storage"
"github.com/hyperledger/aries-framework-go/pkg/secretlock/noop"
)

const errMsgSchema = "credentials do not satisfy requirements"
Expand Down Expand Up @@ -79,7 +86,66 @@ func TestPresentationDefinition_CreateVP(t *testing.T) {
})

t.Run("Checks submission requirements", func(t *testing.T) {
issuerID := uuid.New().String()
issuerID := "did:example:76e12ec712ebc6f1c221ebfeb1f"

vc1JWT := &verifiable.Credential{
Issued: util.NewTime(time.Now()),
Context: []string{verifiable.ContextURI},
Types: []string{verifiable.VCType},
ID: "http://example.edu/credentials/1872",
Subject: []verifiable.Subject{{ID: issuerID}},
Issuer: verifiable.Issuer{ID: issuerID},
CustomFields: map[string]interface{}{
"first_name": "Jesse",
"last_name": "Travis",
"age": 17,
},
// vc as jwt does not use proof, do not set it here.
}

ed25519Signer, err := newCryptoSigner(kms.ED25519Type)
require.NoError(t, err)

vc1JWT.JWT = createEdDSAJWS(t, vc1JWT, ed25519Signer, "76e12ec712ebc6f1c221ebfeb1f", true)

candidateVCs := []*verifiable.Credential{
vc1JWT,
{
Context: []string{verifiable.ContextURI},
Types: []string{verifiable.VCType},
ID: "http://example.edu/credentials/1872",
CustomFields: map[string]interface{}{
"first_name": "Jesse",
},
Proofs: []verifiable.Proof{{"type": "JsonWebSignature2020"}},
},
{
Context: []string{verifiable.ContextURI},
Types: []string{verifiable.VCType},
ID: "http://example.edu/credentials/1872",
Subject: []verifiable.Subject{{ID: issuerID}},
Issuer: verifiable.Issuer{ID: issuerID},
CustomFields: map[string]interface{}{
"first_name": "Jesse",
"last_name": "Travis",
"age": 17,
},
Proofs: []verifiable.Proof{{"type": "JsonWebSignature2020"}},
},
{
Context: []string{verifiable.ContextURI},
Types: []string{verifiable.VCType},
ID: "http://example.edu/credentials/1872",
Subject: []verifiable.Subject{{ID: issuerID}},
Issuer: verifiable.Issuer{ID: issuerID},
CustomFields: map[string]interface{}{
"first_name": "Jesse",
"last_name": "Travis",
"age": 2,
},
Proofs: []verifiable.Proof{{"type": "JsonWebSignature2020"}},
},
}

tests := []struct {
name string
Expand Down Expand Up @@ -107,6 +173,27 @@ func TestPresentationDefinition_CreateVP(t *testing.T) {
LdpVC: &LdpType{ProofType: []string{"JsonWebSignature2020"}},
},
},
{
name: "test JWT format",
format: FormatJWT,
vFormat: &Format{
Jwt: &JwtType{Alg: []string{"EdDSA"}},
},
},
{
name: "test JWTVC format",
format: FormatJWTVC,
vFormat: &Format{
JwtVC: &JwtType{Alg: []string{"EdDSA"}},
},
},
{
name: "test JWTVP format",
format: FormatJWTVP,
vFormat: &Format{
JwtVP: &JwtType{Alg: []string{"EdDSA"}},
},
},
}

for _, tc := range tests {
Expand Down Expand Up @@ -205,46 +292,7 @@ func TestPresentationDefinition_CreateVP(t *testing.T) {
Format: tc.vFormat,
}

vp, err := pd.CreateVP([]*verifiable.Credential{
{
Context: []string{verifiable.ContextURI},
Types: []string{verifiable.VCType},
ID: uuid.New().String(),
CustomFields: map[string]interface{}{
"first_name": "Jesse",
},
// since Format in InputDescriptor works only with proofs, need to add it in the vc.
Proofs: []verifiable.Proof{{"type": "JsonWebSignature2020"}},
},
{
Context: []string{verifiable.ContextURI},
Types: []string{verifiable.VCType},
ID: uuid.New().String(),
Subject: []verifiable.Subject{{ID: issuerID}},
Issuer: verifiable.Issuer{ID: issuerID},
CustomFields: map[string]interface{}{
"first_name": "Jesse",
"last_name": "Travis",
"age": 17,
},
// since Format in InputDescriptor works only with proofs, need to add it in the vc.
Proofs: []verifiable.Proof{{"type": "JsonWebSignature2020"}},
},
{
Context: []string{verifiable.ContextURI},
Types: []string{verifiable.VCType},
ID: uuid.New().String(),
Subject: []verifiable.Subject{{ID: issuerID}},
Issuer: verifiable.Issuer{ID: issuerID},
CustomFields: map[string]interface{}{
"first_name": "Jesse",
"last_name": "Travis",
"age": 2,
},
// since Format in InputDescriptor works only with proofs, need to add it in the vc.
Proofs: []verifiable.Proof{{"type": "JsonWebSignature2020"}},
},
}, lddl)
vp, err := pd.CreateVP(candidateVCs, lddl)

require.NoError(t, err)
require.NotNil(t, vp)
Expand Down Expand Up @@ -1473,6 +1521,41 @@ func TestPresentationDefinition_CreateVP(t *testing.T) {
})
}

func createEdDSAJWS(t *testing.T, cred *verifiable.Credential, signer verifiable.Signer,
keyID string, minimize bool) string {
t.Helper()

jwtClaims, err := cred.JWTClaims(minimize)
require.NoError(t, err)
vcJWT, err := jwtClaims.MarshalJWS(verifiable.EdDSA, signer, cred.Issuer.ID+"#keys-"+keyID)
require.NoError(t, err)

return vcJWT
}

func createKMS() (*localkms.LocalKMS, error) {
p, err := mockkms.NewProviderForKMS(storage.NewMockStoreProvider(), &noop.NoLock{})
if err != nil {
return nil, err
}

return localkms.New("local-lock://custom/master/key/", p)
}

func newCryptoSigner(keyType kms.KeyType) (signature.Signer, error) {
localKMS, err := createKMS()
if err != nil {
return nil, err
}

tinkCrypto, err := tinkcrypto.New()
if err != nil {
return nil, err
}

return signature.NewCryptoSigner(tinkCrypto, localKMS, keyType)
}

func checkSubmission(t *testing.T, vp *verifiable.Presentation, pd *PresentationDefinition) {
t.Helper()

Expand Down
6 changes: 5 additions & 1 deletion pkg/doc/verifiable/presentation.go
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,11 @@ func decodeCredentials(rawCred interface{}, opts *presentationOpts) ([]interface
return nil, fmt.Errorf("decode credential of presentation: %w", err)
}

return credDecoded, nil
vc, err := ParseCredential(credDecoded,
WithJSONLDDocumentLoader(opts.jsonldCredentialOpts.jsonldDocumentLoader),
WithDisabledProofCheck())

return vc, err
}

// return credential in a structure format as is
Expand Down
1 change: 1 addition & 0 deletions pkg/doc/verifiable/presentation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,7 @@ func TestPresentation_decodeCredentials(t *testing.T) {

// single credential - JWS
opts := defaultPresentationOpts()
opts.jsonldCredentialOpts.jsonldDocumentLoader = createTestDocumentLoader(t)
opts.publicKeyFetcher = SingleKey(signer.PublicKeyBytes(), kms.ED25519)
dCreds, err := decodeCredentials(jws, opts)
r.NoError(err)
Expand Down
3 changes: 2 additions & 1 deletion scripts/check_go_integration.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ echo "Running aries-framework-go integration tests..."
PWD=`pwd`
cd test/bdd
go test -count=1 -v -cover . -p 1 -timeout=45m -race
go test -count=1 -v -cover . -p 1 -timeout=30m -race -run presentproof,present_proof_controller,issue_credential,issue_credential_controller,webkms,waci_issuance,verifiable,verifiable_jwt
go test -count=1 -v -cover . -p 1 -timeout=30m -race -run present_proof_controller,issue_credential,issue_credential_controller,webkms,waci_issuance,verifiable,verifiable_jwt
go test -count=1 -v -cover . -p 1 -timeout=30m -race -run presentproof
go test -count=1 -v -cover . -p 1 -timeout=30m -race -run didcomm_remote_crypto,outofbandv2
go test -count=1 -v -cover . -p 1 -timeout=45m -race -run outofband
DEFAULT_KEY_TYPE="ecdsap256ieee1363" DEFAULT_KEY_AGREEMENT_TYPE="p256kw" go test -count=1 -v -cover . -p 1 -timeout=10m -race -run didcommv2
Expand Down
Loading

0 comments on commit 9fc7486

Please sign in to comment.