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

Commit

Permalink
feat: new component for data models - DIDs, signatures, JSON-LD
Browse files Browse the repository at this point in the history
component/models/:
 - did: afgo's DID and DID Doc models.
 - ld: JSON-LD support - data models, context stores, LD-Proofs, canonicalization, etc.
 - signature: signing APIs used in DID Docs etc.
 - util: utility data models needed for other model implementations, but not specific to a given model.

Signed-off-by: Filip Burlacu <Filip.Burlacu@gendigital.com>
  • Loading branch information
Moopli committed Apr 26, 2023
1 parent 3fd663d commit f6f0151
Show file tree
Hide file tree
Showing 220 changed files with 2,677 additions and 1,074 deletions.
2 changes: 2 additions & 0 deletions cmd/aries-agent-mobile/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ require (
github.com/gorilla/mux v1.7.3 // indirect
github.com/hyperledger/aries-framework-go/component/kmscrypto v0.0.0 // indirect
github.com/hyperledger/aries-framework-go/component/log v0.0.0 // indirect
github.com/hyperledger/aries-framework-go/component/models v0.0.0 // indirect
github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20221025204933-b807371b6f1e // indirect
github.com/hyperledger/ursa-wrapper-go v0.3.1 // indirect
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a // indirect
Expand Down Expand Up @@ -72,6 +73,7 @@ replace (
github.com/hyperledger/aries-framework-go => ../../
github.com/hyperledger/aries-framework-go/component/kmscrypto => ../../component/kmscrypto
github.com/hyperledger/aries-framework-go/component/log => ../../component/log
github.com/hyperledger/aries-framework-go/component/models => ../../component/models
// github.com/hyperledger/aries-framework-go/component/storage/edv => ../../component/storage/edv // TODO (#2815) remove this once the wallet package doesn't import edv
github.com/hyperledger/aries-framework-go/component/storageutil => ../../component/storageutil
github.com/hyperledger/aries-framework-go/spi => ../../spi
Expand Down
2 changes: 2 additions & 0 deletions cmd/aries-agent-rest/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ require (
github.com/google/uuid v1.3.0 // indirect
github.com/hyperledger/aries-framework-go/component/kmscrypto v0.0.0 // indirect
github.com/hyperledger/aries-framework-go/component/log v0.0.0 // indirect
github.com/hyperledger/aries-framework-go/component/models v0.0.0 // indirect
github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20221025204933-b807371b6f1e // indirect
github.com/hyperledger/ursa-wrapper-go v0.3.1 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
Expand Down Expand Up @@ -109,6 +110,7 @@ replace (
github.com/hyperledger/aries-framework-go => ../..
github.com/hyperledger/aries-framework-go/component/kmscrypto => ../../component/kmscrypto
github.com/hyperledger/aries-framework-go/component/log => ../../component/log
github.com/hyperledger/aries-framework-go/component/models => ../../component/models
// github.com/hyperledger/aries-framework-go/component/storage/edv => ../../component/storage/edv // TODO (#2815) remove this once the wallet package doesn't import edv
github.com/hyperledger/aries-framework-go/component/storage/leveldb => ../../component/storage/leveldb
github.com/hyperledger/aries-framework-go/component/storageutil => ../../component/storageutil
Expand Down
2 changes: 2 additions & 0 deletions cmd/aries-js-worker/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ require (
github.com/gorilla/mux v1.7.3 // indirect
github.com/hyperledger/aries-framework-go/component/kmscrypto v0.0.0 // indirect
github.com/hyperledger/aries-framework-go/component/log v0.0.0 // indirect
github.com/hyperledger/aries-framework-go/component/models v0.0.0 // indirect
github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20221025204933-b807371b6f1e // indirect
github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20221025204933-b807371b6f1e // indirect
github.com/hyperledger/ursa-wrapper-go v0.3.1 // indirect
Expand Down Expand Up @@ -73,6 +74,7 @@ replace (
github.com/hyperledger/aries-framework-go => ../..
github.com/hyperledger/aries-framework-go/component/kmscrypto => ../../component/kmscrypto
github.com/hyperledger/aries-framework-go/component/log => ../../component/log
github.com/hyperledger/aries-framework-go/component/models => ../../component/models
github.com/hyperledger/aries-framework-go/component/storage/edv => ../../component/storage/edv // TODO (#2815) remove this once the wallet package doesn't import edv
github.com/hyperledger/aries-framework-go/component/storage/indexeddb => ../../component/storage/indexeddb
github.com/hyperledger/aries-framework-go/component/storageutil => ../../component/storageutil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ SPDX-License-Identifier: Apache-2.0
package crypto

import (
cryptoapi "github.com/hyperledger/aries-framework-go/pkg/crypto"
cryptoapi "github.com/hyperledger/aries-framework-go/spi/crypto"
)

// SignFunc mocks Crypto's Sign() function, it's useful for executing custom signing with the help of SignKey.
Expand Down Expand Up @@ -116,22 +116,25 @@ func (c *Crypto) SignMulti(messages [][]byte, kh interface{}) ([]byte, error) {

// VerifyMulti returns a mocked BBS+ verify result.
// returns:
// error in case of errors or nil if signature verification was successful
//
// error in case of errors or nil if signature verification was successful
func (c *Crypto) VerifyMulti(messages [][]byte, signature []byte, kh interface{}) error {
return c.BBSVerifyErr
}

// VerifyProof returns a mocked BBS+ verify signature proof result.
// returns:
// error in case of errors or nil if signature proof verification was successful
//
// error in case of errors or nil if signature proof verification was successful
func (c *Crypto) VerifyProof(revealedMessages [][]byte, proof, nonce []byte, signerPubKH interface{}) error {
return c.VerifyProofErr
}

// DeriveProof returns a mocked BBS+ signature proof value and a mocked error.
// returns:
// signature proof in []byte
// error in case of errors
//
// signature proof in []byte
// error in case of errors
func (c *Crypto) DeriveProof(messages [][]byte, bbsSignature, nonce []byte, revealedIndexes []int,
signerPubKH interface{}) ([]byte, error) {
if c.DeriveProofFn != nil {
Expand All @@ -143,25 +146,28 @@ func (c *Crypto) DeriveProof(messages [][]byte, bbsSignature, nonce []byte, reve

// Blind returns a mocked blinded vals and a mocked error.
// returns:
// blinded values in []byte
// error in case of errors
//
// blinded values in []byte
// error in case of errors
func (c *Crypto) Blind(kh interface{}, values ...map[string]interface{}) ([][]byte, error) {
return c.BlindValue, c.BlindError
}

// GetCorrectnessProof returns a mocked correctness proof value and a mocked error.
// returns:
// correctness proof in []byte
// error in case of errors
//
// correctness proof in []byte
// error in case of errors
func (c *Crypto) GetCorrectnessProof(kh interface{}) ([]byte, error) {
return c.GetCorrectnessProofValue, c.GetCorrectnessProofError
}

// SignWithSecrets returns the mocked signature and correctness proof values and a mocked error.
// returns:
// signature in []byte
// correctness proof in []byte
// error in case of errors
//
// signature in []byte
// correctness proof in []byte
// error in case of errors
func (c *Crypto) SignWithSecrets(kh interface{}, values map[string]interface{},
secrets []byte, correctnessProof []byte, nonces [][]byte, did string) ([]byte, []byte, error) {
return c.SignWithSecretsValue, c.SignWithSecretsProof, c.SignWithSecretsError
Expand Down
32 changes: 16 additions & 16 deletions pkg/doc/did/doc.go → component/models/did/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ import (
"github.com/multiformats/go-multibase"
"github.com/xeipuuv/gojsonschema"

"github.com/hyperledger/aries-framework-go/pkg/common/log"
"github.com/hyperledger/aries-framework-go/pkg/common/model"
"github.com/hyperledger/aries-framework-go/pkg/doc/jose/jwk"
"github.com/hyperledger/aries-framework-go/pkg/doc/signature/jsonld"
sigproof "github.com/hyperledger/aries-framework-go/pkg/doc/signature/proof"
"github.com/hyperledger/aries-framework-go/pkg/doc/signature/verifier"
"github.com/hyperledger/aries-framework-go/component/kmscrypto/doc/jose/jwk"
"github.com/hyperledger/aries-framework-go/component/log"
"github.com/hyperledger/aries-framework-go/component/models/did/endpoint"
"github.com/hyperledger/aries-framework-go/component/models/ld/processor"
sigproof "github.com/hyperledger/aries-framework-go/component/models/ld/proof"
"github.com/hyperledger/aries-framework-go/component/models/signature/verifier"
)

const (
Expand Down Expand Up @@ -377,7 +377,7 @@ type Service struct {
Priority interface{} `json:"priority,omitempty"`
RecipientKeys []string `json:"recipientKeys,omitempty"`
RoutingKeys []string `json:"routingKeys,omitempty"`
ServiceEndpoint model.Endpoint `json:"serviceEndpoint"`
ServiceEndpoint endpoint.Endpoint `json:"serviceEndpoint"`
Accept []string `json:"accept,omitempty"`
Properties map[string]interface{} `json:"properties,omitempty"`
recipientKeysRelativeURL map[string]bool
Expand Down Expand Up @@ -675,14 +675,14 @@ func populateServices(didID, baseURI string, rawServices []map[string]interface{
routingKeys, routingKeysRelativeURL = populateKeys(routingKeys, didID, baseURI)
}

var sp model.Endpoint
var sp endpoint.Endpoint

//nolint:nestif
if epEntry, ok := rawService[jsonldServicePoint]; ok {
uriStr, ok := epEntry.(string)
// for now handling DIDComm V1 or V2 only.
if ok { // DIDComm V1 format.
sp = model.NewDIDCommV1Endpoint(uriStr)
sp = endpoint.NewDIDCommV1Endpoint(uriStr)
} else if epEntry != nil { // DIDComm V2 format (first valid entry for now).
entries, ok := epEntry.([]interface{})
if ok && len(entries) > 0 {
Expand All @@ -691,14 +691,14 @@ func populateServices(didID, baseURI string, rawServices []map[string]interface{
epURI := stringEntry(firstEntry["uri"])
epAccept := stringArray(firstEntry["accept"])
epRoutingKeys := stringArray(firstEntry["routingKeys"])
sp = model.NewDIDCommV2Endpoint([]model.DIDCommV2Endpoint{
sp = endpoint.NewDIDCommV2Endpoint([]endpoint.DIDCommV2Endpoint{
{URI: epURI, Accept: epAccept, RoutingKeys: epRoutingKeys},
})
}
}
coreServices, ok := epEntry.(map[string]interface{}) // DID Core
if ok && len(coreServices) > 0 {
sp = model.NewDIDCoreEndpoint(coreServices)
sp = endpoint.NewDIDCoreEndpoint(coreServices)
}
}
}
Expand Down Expand Up @@ -1208,7 +1208,7 @@ func (doc *Doc) MarshalJSON() ([]byte, error) {
}

// VerifyProof verifies document proofs.
func (doc *Doc) VerifyProof(suites []verifier.SignatureSuite, jsonldOpts ...jsonld.ProcessorOpts) error {
func (doc *Doc) VerifyProof(suites []verifier.SignatureSuite, jsonldOpts ...processor.Opts) error {
if len(doc.Proof) == 0 {
return ErrProofNotFound
}
Expand Down Expand Up @@ -1360,8 +1360,8 @@ func populateRawServices(services []Service, didID, baseURI string) []map[string
logger.Debugf("URI field of DIDComm V2 endpoint missing or invalid, it will be ignored: %w", err)
}

if services[i].ServiceEndpoint.Type() == model.DIDCommV2 {
services[i].ServiceEndpoint = model.NewDIDCommV2Endpoint([]model.DIDCommV2Endpoint{
if services[i].ServiceEndpoint.Type() == endpoint.DIDCommV2 {
services[i].ServiceEndpoint = endpoint.NewDIDCommV2Endpoint([]endpoint.DIDCommV2Endpoint{
{URI: sepURI, Accept: sepAccept, RoutingKeys: sepRoutingKeys},
})
}
Expand All @@ -1384,7 +1384,7 @@ func populateRawServices(services []Service, didID, baseURI string) []map[string

rawService[jsonldType] = services[i].Type

if services[i].ServiceEndpoint.Type() == model.DIDCommV2 { //nolint: gocritic
if services[i].ServiceEndpoint.Type() == endpoint.DIDCommV2 { //nolint: gocritic
serviceEndpointMap := []map[string]interface{}{{"uri": sepURI}}
if len(sepAccept) > 0 {
serviceEndpointMap[0]["accept"] = sepAccept
Expand All @@ -1395,7 +1395,7 @@ func populateRawServices(services []Service, didID, baseURI string) []map[string
}

rawService[jsonldServicePoint] = serviceEndpointMap
} else if services[i].ServiceEndpoint.Type() == model.DIDCommV1 {
} else if services[i].ServiceEndpoint.Type() == endpoint.DIDCommV1 {
rawService[jsonldServicePoint] = sepURI
} else {
bytes, err := services[i].ServiceEndpoint.MarshalJSON()
Expand Down
46 changes: 23 additions & 23 deletions pkg/doc/did/doc_test.go → component/models/did/doc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@ import (
gojose "github.com/go-jose/go-jose/v3"
"github.com/stretchr/testify/require"

"github.com/hyperledger/aries-framework-go/pkg/common/model"
"github.com/hyperledger/aries-framework-go/pkg/doc/jose/jwk"
"github.com/hyperledger/aries-framework-go/pkg/doc/signature/signer"
"github.com/hyperledger/aries-framework-go/pkg/doc/signature/suite"
"github.com/hyperledger/aries-framework-go/pkg/doc/signature/suite/ed25519signature2018"
"github.com/hyperledger/aries-framework-go/pkg/doc/signature/suite/ed25519signature2020"
"github.com/hyperledger/aries-framework-go/pkg/doc/signature/verifier"
"github.com/hyperledger/aries-framework-go/pkg/internal/ldtestutil"
"github.com/hyperledger/aries-framework-go/component/kmscrypto/doc/jose/jwk"
"github.com/hyperledger/aries-framework-go/component/models/did/endpoint"
"github.com/hyperledger/aries-framework-go/component/models/ld/testutil"
"github.com/hyperledger/aries-framework-go/component/models/signature/signer"
"github.com/hyperledger/aries-framework-go/component/models/signature/suite"
"github.com/hyperledger/aries-framework-go/component/models/signature/suite/ed25519signature2018"
"github.com/hyperledger/aries-framework-go/component/models/signature/suite/ed25519signature2020"
"github.com/hyperledger/aries-framework-go/component/models/signature/verifier"
)

const pemPK = `-----BEGIN PUBLIC KEY-----
Expand Down Expand Up @@ -153,7 +153,7 @@ func TestValidWithDocBase(t *testing.T) {
ID: "did:example:123456789abcdefghi#inbox",
Type: "SocialWebInboxService",
relativeURL: true,
ServiceEndpoint: model.NewDIDCommV1Endpoint("https://social.example.com/83hfh37dj"),
ServiceEndpoint: endpoint.NewDIDCommV1Endpoint("https://social.example.com/83hfh37dj"),
Properties: map[string]interface{}{"spamCost": map[string]interface{}{"amount": "0.50", "currency": "USD"}},
},
{
Expand All @@ -163,7 +163,7 @@ func TestValidWithDocBase(t *testing.T) {
relativeURL: true,
RecipientKeys: []string{"did:example:123456789abcdefghi#key2"},
RoutingKeys: []string{"did:example:123456789abcdefghi#key2"},
ServiceEndpoint: model.NewDIDCommV1Endpoint("https://agent.example.com/"),
ServiceEndpoint: endpoint.NewDIDCommV1Endpoint("https://agent.example.com/"),
Properties: map[string]interface{}{},
recipientKeysRelativeURL: map[string]bool{"did:example:123456789abcdefghi#key2": true},
routingKeysRelativeURL: map[string]bool{"did:example:123456789abcdefghi#key2": true},
Expand Down Expand Up @@ -420,7 +420,7 @@ func TestValid(t *testing.T) {
{
ID: "did:example:123456789abcdefghi#inbox",
Type: []interface{}{"SocialWebInboxService"},
ServiceEndpoint: model.NewDIDCommV1Endpoint("https://social.example.com/83hfh37dj"),
ServiceEndpoint: endpoint.NewDIDCommV1Endpoint("https://social.example.com/83hfh37dj"),
Properties: map[string]interface{}{"spamCost": map[string]interface{}{"amount": "0.50", "currency": "USD"}},
},
{
Expand All @@ -429,7 +429,7 @@ func TestValid(t *testing.T) {
Priority: float64(0),
RecipientKeys: []string{"did:example:123456789abcdefghi#key2"},
RoutingKeys: []string{"did:example:123456789abcdefghi#key2"},
ServiceEndpoint: model.NewDIDCommV1Endpoint("https://agent.example.com/"),
ServiceEndpoint: endpoint.NewDIDCommV1Endpoint("https://agent.example.com/"),
Properties: map[string]interface{}{},
recipientKeysRelativeURL: map[string]bool{"did:example:123456789abcdefghi#key2": false},
routingKeysRelativeURL: map[string]bool{"did:example:123456789abcdefghi#key2": false},
Expand All @@ -439,7 +439,7 @@ func TestValid(t *testing.T) {
Type: "DIDCommMessaging",
Priority: float64(0),
RecipientKeys: []string{"did:example:123456789abcdefghi#key2"},
ServiceEndpoint: model.NewDIDCommV2Endpoint([]model.DIDCommV2Endpoint{{
ServiceEndpoint: endpoint.NewDIDCommV2Endpoint([]endpoint.DIDCommV2Endpoint{{
URI: "https://agent.example.com/",
Accept: []string{"didcomm/v2"},
RoutingKeys: []string{"did:example:123456789abcdefghi#key2"},
Expand Down Expand Up @@ -1390,25 +1390,25 @@ func TestVerifyProof(t *testing.T) {
doc, err := ParseDocument(signedDoc)
require.Nil(t, err)
require.NotNil(t, doc)
err = doc.VerifyProof([]verifier.SignatureSuite{s}, ldtestutil.WithDocumentLoader(t))
err = doc.VerifyProof([]verifier.SignatureSuite{s}, testutil.WithDocumentLoader(t))
require.NoError(t, err)

// error - no suites are passed, verifier is not created
err = doc.VerifyProof([]verifier.SignatureSuite{}, ldtestutil.WithDocumentLoader(t))
err = doc.VerifyProof([]verifier.SignatureSuite{}, testutil.WithDocumentLoader(t))
require.Error(t, err)
require.Contains(t, err.Error(), "create verifier")

// error - doc with invalid proof value
doc.Proof[0].ProofValue = []byte("invalid")
err = doc.VerifyProof([]verifier.SignatureSuite{s}, ldtestutil.WithDocumentLoader(t))
err = doc.VerifyProof([]verifier.SignatureSuite{s}, testutil.WithDocumentLoader(t))
require.NotNil(t, err)
require.Contains(t, err.Error(), "ed25519: invalid signature")

// error - doc with no proof
doc, err = ParseDocument([]byte(d))
require.NoError(t, err)
require.NotNil(t, doc)
err = doc.VerifyProof([]verifier.SignatureSuite{s}, ldtestutil.WithDocumentLoader(t))
err = doc.VerifyProof([]verifier.SignatureSuite{s}, testutil.WithDocumentLoader(t))
require.Equal(t, ErrProofNotFound, err)
require.Contains(t, err.Error(), "proof not found")
}
Expand All @@ -1430,25 +1430,25 @@ func TestVerifyProofWithEd25519signature2020(t *testing.T) {
doc, err := ParseDocument(signedDoc)
require.Nil(t, err)
require.NotNil(t, doc)
err = doc.VerifyProof([]verifier.SignatureSuite{s}, ldtestutil.WithDocumentLoader(t))
err = doc.VerifyProof([]verifier.SignatureSuite{s}, testutil.WithDocumentLoader(t))
require.NoError(t, err)

// error - no suites are passed, verifier is not created
err = doc.VerifyProof([]verifier.SignatureSuite{}, ldtestutil.WithDocumentLoader(t))
err = doc.VerifyProof([]verifier.SignatureSuite{}, testutil.WithDocumentLoader(t))
require.Error(t, err)
require.Contains(t, err.Error(), "create verifier")

// error - doc with invalid proof value
doc.Proof[0].ProofValue = []byte("invalid")
err = doc.VerifyProof([]verifier.SignatureSuite{s}, ldtestutil.WithDocumentLoader(t))
err = doc.VerifyProof([]verifier.SignatureSuite{s}, testutil.WithDocumentLoader(t))
require.NotNil(t, err)
require.Contains(t, err.Error(), "ed25519: invalid signature")

// error - doc with no proof
doc, err = ParseDocument([]byte(d))
require.NoError(t, err)
require.NotNil(t, doc)
err = doc.VerifyProof([]verifier.SignatureSuite{s}, ldtestutil.WithDocumentLoader(t))
err = doc.VerifyProof([]verifier.SignatureSuite{s}, testutil.WithDocumentLoader(t))
require.Equal(t, ErrProofNotFound, err)
require.Contains(t, err.Error(), "proof not found")
}
Expand Down Expand Up @@ -2032,7 +2032,7 @@ func createSignedDidDocument(t *testing.T, privKey, pubKey []byte) []byte {
s := signer.New(ed25519signature2018.New(
suite.WithSigner(getSigner(privKey))))

signedDoc, err := s.Sign(context, jsonDoc, ldtestutil.WithDocumentLoader(t))
signedDoc, err := s.Sign(context, jsonDoc, testutil.WithDocumentLoader(t))
require.NoError(t, err)

return signedDoc
Expand All @@ -2059,7 +2059,7 @@ func createSignedDidDocumentWithEd25519signature2020(t *testing.T, privKey, pubK
s := signer.New(ed25519signature2020.New(
suite.WithSigner(getSigner(privKey))))

signedDoc, err := s.Sign(context, jsonDoc, ldtestutil.WithDocumentLoader(t))
signedDoc, err := s.Sign(context, jsonDoc, testutil.WithDocumentLoader(t))
require.NoError(t, err)

return signedDoc
Expand Down
Loading

0 comments on commit f6f0151

Please sign in to comment.