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

Commit

Permalink
support ability in AFGO to create and parse vc and vp in JWT format
Browse files Browse the repository at this point in the history
Signed-off-by: Mykhailo Sizov <mykhailo.sizov@securekey.com>
  • Loading branch information
mishasizov-SK committed Aug 15, 2022
1 parent e05b76b commit 046adf0
Show file tree
Hide file tree
Showing 12 changed files with 478 additions and 60 deletions.
29 changes: 19 additions & 10 deletions pkg/doc/jwt/verifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,16 +56,25 @@ type BasicVerifier struct {
func NewVerifier(resolver KeyResolver) *BasicVerifier {
// TODO Support pluggable JWS verifiers
// (https://github.com/hyperledger/aries-framework-go/issues/1267)
compositeVerifier := jose.NewCompositeAlgSigVerifier(
jose.AlgSignatureVerifier{
Alg: signatureEdDSA,
Verifier: getVerifier(resolver, VerifyEdDSA),
},
jose.AlgSignatureVerifier{
Alg: signatureRS256,
Verifier: getVerifier(resolver, VerifyRS256),
},
)
verifiers := []verifier.SignatureVerifier{
verifier.NewECDSAES256SignatureVerifier(),
verifier.NewECDSAES384SignatureVerifier(),
verifier.NewECDSAES521SignatureVerifier(),
verifier.NewEd25519SignatureVerifier(),
verifier.NewECDSASecp256k1SignatureVerifier(),
verifier.NewRSAPS256SignatureVerifier(),
verifier.NewRSARS256SignatureVerifier(),
}

algVerifiers := make([]jose.AlgSignatureVerifier, 0, len(verifiers))
for _, v := range verifiers {
algVerifiers = append(algVerifiers, jose.AlgSignatureVerifier{
Alg: v.Algorithm(),
Verifier: getVerifier(resolver, v.Verify),
})
}

compositeVerifier := jose.NewCompositeAlgSigVerifier(algVerifiers[0], algVerifiers[1:]...)
// TODO ECDSA to support NIST P256 curve
// https://github.com/hyperledger/aries-framework-go/issues/1266

Expand Down
2 changes: 1 addition & 1 deletion scripts/check_go_integration.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ 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
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 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
2 changes: 2 additions & 0 deletions test/bdd/bddtests_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/hyperledger/aries-framework-go/test/bdd/pkg/didresolver"
"github.com/hyperledger/aries-framework-go/test/bdd/pkg/introduce"
"github.com/hyperledger/aries-framework-go/test/bdd/pkg/issuecredential"
"github.com/hyperledger/aries-framework-go/test/bdd/pkg/jwt"
"github.com/hyperledger/aries-framework-go/test/bdd/pkg/ld"
"github.com/hyperledger/aries-framework-go/test/bdd/pkg/mediator"
"github.com/hyperledger/aries-framework-go/test/bdd/pkg/messaging"
Expand Down Expand Up @@ -210,6 +211,7 @@ func features() []feature {
rfc0593.NewRestSDKSteps(),
ld.NewLDControllerSteps(),
ld.NewSDKSteps(),
jwt.NewJWTSDKSteps(),
connection.NewSDKSteps(),
connection.NewControllerSteps(),
webkms.NewCryptoSDKSteps(),
Expand Down
20 changes: 20 additions & 0 deletions test/bdd/features/jwt.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#
# Copyright SecureKey Technologies Inc. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#

@verifiable_jwt
Feature: Issue and verify Verifiable Credential and Verifiable Presentation in JWS format

Scenario Outline: Issue VC - verify VC - create VP - verify VP
Given crypto algorithm "<crypto>"
And "Berkley" issues VC at "2022-04-12" regarding "Master Degree" to "Alice"
Then "Alice" receives the VC and verifies it
Then "Alice" embeds the VC into VP
Then "Alice" verifies VP
Examples:
| crypto |
| "Ed25519" |
| "ECDSA Secp256r1" |
| "ECDSA Secp384r1" |
120 changes: 120 additions & 0 deletions test/bdd/pkg/jwt/credential.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package jwt

import (
"errors"
"time"

"github.com/hyperledger/aries-framework-go/pkg/doc/util"
"github.com/hyperledger/aries-framework-go/pkg/doc/verifiable"
bddverifiable "github.com/hyperledger/aries-framework-go/test/bdd/pkg/verifiable"
)

func (s *SDKSteps) issueCredential(issuer, issuedAt, subject, holder string) error {
err := s.createDID(issuer, holder)
if err != nil {
return err
}

vcToIssue, err := s.createVC(issuedAt, subject, issuer)
if err != nil {
return err
}

vcBytes, err := s.addVCProof(vcToIssue, issuer)
if err != nil {
return err
}

s.issuedVCBytes = vcBytes

return nil
}

func (s *SDKSteps) verifyCredential(holder string) error {
vdr := s.bddContext.AgentCtx[holder].VDRegistry()
pKeyFetcher := verifiable.NewVDRKeyResolver(vdr).PublicKeyFetcher()

loader, err := bddverifiable.CreateDocumentLoader()
if err != nil {
return err
}

s.issuedVC, err = verifiable.ParseCredential(s.issuedVCBytes,
verifiable.WithPublicKeyFetcher(pKeyFetcher),
verifiable.WithJSONLDDocumentLoader(loader))
if err != nil {
return err
}

if s.issuedVC == nil {
return errors.New("received nil credential")
}

return nil
}

func (s *SDKSteps) createVC(issuedAt, subject, issuer string) (*verifiable.Credential, error) {
const dateLayout = "2006-01-02"

issued, err := time.Parse(dateLayout, issuedAt)
if err != nil {
return nil, err
}

vcToIssue := &verifiable.Credential{
Context: []string{
"https://www.w3.org/2018/credentials/v1",
"https://www.w3.org/2018/credentials/examples/v1",
},
ID: "http://example.edu/credentials/1872",
Types: []string{
"VerifiableCredential",
"UniversityDegreeCredential",
},
Subject: subject,
Issuer: verifiable.Issuer{
ID: s.getPublicDID(issuer).ID,
CustomFields: verifiable.CustomFields{"name": issuer},
},
Issued: util.NewTime(issued),
}

return vcToIssue, nil
}

func (s *SDKSteps) addVCProof(vc *verifiable.Credential, issuer string) ([]byte, error) {
doc := s.getPublicDID(issuer)
pubKeyID := doc.VerificationMethod[0].ID

jwtClaims, err := vc.JWTClaims(false)
if err != nil {
return nil, err
}

publicKeyJWK := s.bddContext.PublicKeys[issuer]

keyType, err := publicKeyJWK.KeyType()
if err != nil {
return nil, err
}

jwsAlgo, err := verifiable.KeyTypeToJWSAlgo(keyType)
if err != nil {
return nil, err
}

signer := s.getSigner(issuer)

jws, err := jwtClaims.MarshalJWS(jwsAlgo, signer, pubKeyID)
if err != nil {
return nil, err
}

return []byte(jws), nil
}
49 changes: 49 additions & 0 deletions test/bdd/pkg/jwt/did.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package jwt

import (
"github.com/hyperledger/aries-framework-go/pkg/doc/did"
bddagent "github.com/hyperledger/aries-framework-go/test/bdd/agent"
bddDIDExchange "github.com/hyperledger/aries-framework-go/test/bdd/pkg/didexchange"
"github.com/hyperledger/aries-framework-go/test/bdd/pkg/didresolver"
)

func (s *SDKSteps) createDID(issuer, holder string) error {
const (
inboundHost = "localhost"
inboundPort = "random"
endpointURL = "${SIDETREE_URL}"
acceptDidMethod = "sidetree"
)

participants := issuer + "," + holder
agentSDK := bddagent.NewSDKSteps()
agentSDK.SetContext(s.bddContext)

err := agentSDK.CreateAgentWithHTTPDIDResolver(participants, inboundHost, inboundPort, endpointURL, acceptDidMethod)
if err != nil {
return err
}

if err := s.createKeys(participants); err != nil {
return err
}

if err := didresolver.CreateDIDDocument(s.bddContext, participants, "JsonWebKey2020"); err != nil {
return err
}

didExchangeSDK := bddDIDExchange.NewDIDExchangeSDKSteps()
didExchangeSDK.SetContext(s.bddContext)

return didExchangeSDK.WaitForPublicDID(participants, 10)
}

func (s *SDKSteps) getPublicDID(agentName string) *did.Doc {
return s.bddContext.PublicDIDDocs[agentName]
}
Loading

0 comments on commit 046adf0

Please sign in to comment.