From 86192786b468d7e2c934e750da0c099070f49c67 Mon Sep 17 00:00:00 2001
From: Filip Burlacu
Date: Tue, 1 Mar 2022 10:44:23 -0500
Subject: [PATCH 01/54] fix: allow didcomm v1 messages to use didcomm v2
from-did
Signed-off-by: Filip Burlacu
---
pkg/didcomm/dispatcher/inbound/inbound_message_handler.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pkg/didcomm/dispatcher/inbound/inbound_message_handler.go b/pkg/didcomm/dispatcher/inbound/inbound_message_handler.go
index 33bafbecd..2ca8bb768 100644
--- a/pkg/didcomm/dispatcher/inbound/inbound_message_handler.go
+++ b/pkg/didcomm/dispatcher/inbound/inbound_message_handler.go
@@ -189,7 +189,7 @@ func (handler *MessageHandler) HandleInboundEnvelope(envelope *transport.Envelop
if foundMessageService != nil {
if !gotDIDs {
- myDID, theirDID, err = handler.getDIDs(envelope, nil)
+ myDID, theirDID, err = handler.getDIDs(envelope, msg)
if err != nil {
return fmt.Errorf("inbound message handler: %w", err)
}
From 645dec4479d264334951c99f01ff6888c3ab2305 Mon Sep 17 00:00:00 2001
From: Filip Burlacu
Date: Tue, 1 Mar 2022 19:08:25 -0500
Subject: [PATCH 02/54] feat: /kms/import supports importing ecdhkw private
keys
Signed-off-by: Filip Burlacu
---
pkg/controller/command/kms/command.go | 6 ++-
pkg/controller/command/kms/command_test.go | 18 ++++++++
pkg/kms/localkms/localkms_test.go | 53 +++++++++++++++++++---
pkg/kms/localkms/privkey_import.go | 47 +++++++++++++++++++
4 files changed, 117 insertions(+), 7 deletions(-)
diff --git a/pkg/controller/command/kms/command.go b/pkg/controller/command/kms/command.go
index bc1dfb335..70064baec 100644
--- a/pkg/controller/command/kms/command.go
+++ b/pkg/controller/command/kms/command.go
@@ -136,7 +136,11 @@ func (o *Command) ImportKey(rw io.Writer, req io.Reader) command.Error {
case "Ed25519":
keyType = kms.ED25519Type
case "P-256":
- keyType = kms.ECDSAP256TypeIEEEP1363
+ if j.Use == "enc" {
+ keyType = kms.NISTP256ECDHKWType
+ } else {
+ keyType = kms.ECDSAP256TypeIEEEP1363
+ }
case "BLS12381_G2":
keyType = kms.BLS12381G2Type
default:
diff --git a/pkg/controller/command/kms/command_test.go b/pkg/controller/command/kms/command_test.go
index e5a93fb70..1d997fbf8 100644
--- a/pkg/controller/command/kms/command_test.go
+++ b/pkg/controller/command/kms/command_test.go
@@ -159,6 +159,24 @@ func TestImportKey(t *testing.T) {
var getRW bytes.Buffer
cmdErr := cmd.ImportKey(&getRW, bytes.NewBuffer(jwkBytes))
require.NoError(t, cmdErr)
+
+ p256Key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
+ require.NoError(t, err)
+
+ j = jwk.JWK{
+ JSONWebKey: jose.JSONWebKey{
+ Key: p256Key,
+ KeyID: "kid",
+ Algorithm: "ECDSA",
+ Use: "enc",
+ },
+ }
+
+ jwkBytes, err = json.Marshal(&j)
+ require.NoError(t, err)
+
+ cmdErr = cmd.ImportKey(&getRW, bytes.NewBuffer(jwkBytes))
+ require.NoError(t, cmdErr)
})
t.Run("test import key - error", func(t *testing.T) {
diff --git a/pkg/kms/localkms/localkms_test.go b/pkg/kms/localkms/localkms_test.go
index b019acd9d..3d9d6b528 100644
--- a/pkg/kms/localkms/localkms_test.go
+++ b/pkg/kms/localkms/localkms_test.go
@@ -14,6 +14,7 @@ import (
"crypto/sha256"
"crypto/x509"
"encoding/base64"
+ "encoding/json"
"errors"
"fmt"
"io/ioutil"
@@ -25,6 +26,7 @@ import (
"github.com/google/tink/go/subtle/random"
"github.com/stretchr/testify/require"
+ "github.com/hyperledger/aries-framework-go/pkg/crypto"
"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/kms"
@@ -384,7 +386,7 @@ func TestLocalKMS_Success(t *testing.T) {
}
}
-func TestLocalKMS_ImportPrivateKey(t *testing.T) {
+func TestLocalKMS_ImportPrivateKey(t *testing.T) { // nolint:gocyclo
// create a real (not mocked) master key and secret lock to test the KMS end to end
sl := createMasterKeyAndSecretLock(t)
@@ -426,6 +428,21 @@ func TestLocalKMS_ImportPrivateKey(t *testing.T) {
keyType: kms.ECDSAP521TypeDER,
curve: elliptic.P521(),
},
+ {
+ tcName: "import private key using NISTP256ECDHKW type",
+ keyType: kms.NISTP256ECDHKWType,
+ curve: elliptic.P256(),
+ },
+ {
+ tcName: "import private key using NISTP384ECDHKW type",
+ keyType: kms.NISTP384ECDHKWType,
+ curve: elliptic.P384(),
+ },
+ {
+ tcName: "import private key using NISTP521ECDHKW type",
+ keyType: kms.NISTP521ECDHKWType,
+ curve: elliptic.P521(),
+ },
{
tcName: "import private key using ECDSAP256TypeIEEEP1363 type",
keyType: kms.ECDSAP256TypeIEEEP1363,
@@ -532,18 +549,42 @@ func TestLocalKMS_ImportPrivateKey(t *testing.T) {
}
// export marshaled public key to verify it against the original public key (marshalled)
- pubKeyBytes, err := kmsService.ExportPubKeyBytes(ksID)
+ actualPubKey, err := kmsService.ExportPubKeyBytes(ksID)
require.NoError(t, err)
+ var expectedPubKey []byte
+
switch tt.keyType {
case kms.ECDSAP256TypeDER, kms.ECDSAP384TypeDER, kms.ECDSAP521TypeDER:
- pubKey, err := x509.MarshalPKIXPublicKey(privKey.Public())
+ expectedPubKey, err = x509.MarshalPKIXPublicKey(privKey.Public())
require.NoError(t, err)
- require.EqualValues(t, pubKey, pubKeyBytes)
case kms.ECDSAP256TypeIEEEP1363, kms.ECDSAP384TypeIEEEP1363, kms.ECDSAP521TypeIEEEP1363:
- pubKey := elliptic.Marshal(tt.curve, privKey.X, privKey.Y)
- require.EqualValues(t, pubKey, pubKeyBytes)
+ expectedPubKey = elliptic.Marshal(tt.curve, privKey.X, privKey.Y)
+ case kms.NISTP256ECDHKWType, kms.NISTP384ECDHKWType, kms.NISTP521ECDHKWType:
+ var curveName string
+
+ switch tt.curve.Params().Name {
+ case "P-256":
+ curveName = "NIST_P256"
+ case "P-384":
+ curveName = "NIST_P384"
+ case "P-521":
+ curveName = "NIST_P521"
+ }
+
+ cryptoKey := &crypto.PublicKey{
+ KID: ksID,
+ X: privKey.PublicKey.X.Bytes(),
+ Y: privKey.PublicKey.Y.Bytes(),
+ Curve: curveName,
+ Type: "EC",
+ }
+
+ expectedPubKey, err = json.Marshal(cryptoKey)
+ require.NoError(t, err)
}
+
+ require.EqualValues(t, expectedPubKey, actualPubKey)
})
}
}
diff --git a/pkg/kms/localkms/privkey_import.go b/pkg/kms/localkms/privkey_import.go
index f2756f2d5..6272b1cf4 100644
--- a/pkg/kms/localkms/privkey_import.go
+++ b/pkg/kms/localkms/privkey_import.go
@@ -20,7 +20,9 @@ import (
tinkpb "github.com/google/tink/go/proto/tink_go_proto"
"github.com/hyperledger/aries-framework-go/pkg/crypto/primitive/bbs12381g2pub"
+ "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite/ecdh"
bbspb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/bbs_go_proto"
+ ecdhpb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/ecdh_aead_go_proto"
"github.com/hyperledger/aries-framework-go/pkg/kms"
)
@@ -28,6 +30,8 @@ const (
ecdsaSignerTypeURL = "type.googleapis.com/google.crypto.tink.EcdsaPrivateKey"
ed25519SignerTypeURL = "type.googleapis.com/google.crypto.tink.Ed25519PrivateKey"
bbsSignerKeyTypeURL = "type.hyperledger.org/hyperledger.aries.crypto.tink.BBSPrivateKey"
+
+ nistpECDHKWPrivateKeyTypeURL = "type.hyperledger.org/hyperledger.aries.crypto.tink.NistPEcdhKwPrivateKey"
)
func (l *LocalKMS) importECDSAKey(privKey *ecdsa.PrivateKey, kt kms.KeyType,
@@ -40,6 +44,8 @@ func (l *LocalKMS) importECDSAKey(privKey *ecdsa.PrivateKey, kt kms.KeyType,
}
switch kt {
+ case kms.NISTP256ECDHKWType, kms.NISTP384ECDHKWType, kms.NISTP521ECDHKWType:
+ return l.buildAndImportECDSAPrivateKeyAsECDHKW(privKey, kt, opts...)
case kms.ECDSAP256TypeDER:
params = &ecdsapb.EcdsaParams{
Curve: commonpb.EllipticCurveType_NIST_P256,
@@ -90,6 +96,47 @@ func (l *LocalKMS) importECDSAKey(privKey *ecdsa.PrivateKey, kt kms.KeyType,
return l.importKeySet(ks, opts...)
}
+func (l *LocalKMS) buildAndImportECDSAPrivateKeyAsECDHKW(privKey *ecdsa.PrivateKey, kt kms.KeyType,
+ opts ...kms.PrivateKeyOpts) (string, *keyset.Handle, error) {
+ var keyTemplate *tinkpb.KeyTemplate
+
+ switch kt {
+ case kms.NISTP256ECDHKWType:
+ keyTemplate = ecdh.NISTP256ECDHKWKeyTemplate()
+ case kms.NISTP384ECDHKWType:
+ keyTemplate = ecdh.NISTP384ECDHKWKeyTemplate()
+ case kms.NISTP521ECDHKWType:
+ keyTemplate = ecdh.NISTP521ECDHKWKeyTemplate()
+ }
+
+ keyFormat := new(ecdhpb.EcdhAeadKeyFormat)
+
+ err := proto.Unmarshal(keyTemplate.Value, keyFormat)
+ if err != nil {
+ return "", nil, fmt.Errorf("invalid key format")
+ }
+
+ priv := &ecdhpb.EcdhAeadPrivateKey{
+ Version: 0,
+ KeyValue: privKey.D.Bytes(),
+ PublicKey: &ecdhpb.EcdhAeadPublicKey{
+ Version: 0,
+ Params: keyFormat.Params,
+ X: privKey.PublicKey.X.Bytes(),
+ Y: privKey.PublicKey.Y.Bytes(),
+ },
+ }
+
+ privBytes, err := proto.Marshal(priv)
+ if err != nil {
+ return "", nil, fmt.Errorf("marshal protobuf: %w", err)
+ }
+
+ ks := newKeySet(nistpECDHKWPrivateKeyTypeURL, privBytes, tinkpb.KeyData_ASYMMETRIC_PRIVATE)
+
+ return l.importKeySet(ks, opts...)
+}
+
func (l *LocalKMS) importKeySet(ks *tinkpb.Keyset, opts ...kms.PrivateKeyOpts) (string, *keyset.Handle, error) {
ksID, err := l.writeImportedKey(ks, opts...)
if err != nil {
From 226de71aee89de2e483095f77f6b6fbf4b3368a3 Mon Sep 17 00:00:00 2001
From: Baha Shaaban
Date: Wed, 2 Mar 2022 11:10:55 -0500
Subject: [PATCH 03/54] feat: add BatchCrypto support in EDV
This change includes EDV batch Crypto computation to help support combining all MAC/Encryption/KW operations in one 1 call
Part of #3175
Signed-off-by: Baha Shaaban
---
cmd/aries-js-worker/go.mod | 6 +-
cmd/aries-js-worker/go.sum | 8 +-
.../edv/batchencryptedformatter_test.go | 366 ++++++++++++++++++
component/storage/edv/encryptedformatter.go | 50 ++-
.../storage/edv/encryptedformatter_test.go | 37 +-
component/storage/edv/go.mod | 31 +-
component/storage/edv/go.sum | 68 +++-
component/storage/edv/maccrypto.go | 36 ++
component/storage/edv/restprovider_test.go | 6 +-
scripts/start_edv_test_docker_images.sh | 0
10 files changed, 553 insertions(+), 55 deletions(-)
create mode 100644 component/storage/edv/batchencryptedformatter_test.go
mode change 100644 => 100755 scripts/start_edv_test_docker_images.sh
diff --git a/cmd/aries-js-worker/go.mod b/cmd/aries-js-worker/go.mod
index 01db5a73c..5b5e627c3 100644
--- a/cmd/aries-js-worker/go.mod
+++ b/cmd/aries-js-worker/go.mod
@@ -8,9 +8,9 @@ go 1.17
require (
github.com/google/uuid v1.1.2
- github.com/hyperledger/aries-framework-go v0.1.7-0.20210603210127-e57b8c94e3cf
+ github.com/hyperledger/aries-framework-go v0.1.8-0.20220217153004-1622c70e5767
github.com/hyperledger/aries-framework-go/component/storage/indexeddb v0.0.0-00010101000000-000000000000
- github.com/hyperledger/aries-framework-go/spi v0.0.0-20210820175050-dcc7a225178d
+ github.com/hyperledger/aries-framework-go/spi v0.0.0-20220217153004-1622c70e5767
github.com/mitchellh/mapstructure v1.3.0
github.com/stretchr/testify v1.7.0
)
@@ -30,7 +30,7 @@ require (
github.com/google/tink/go v1.6.1-0.20210519071714-58be99b3c4d0 // indirect
github.com/gorilla/mux v1.7.3 // indirect
github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20210820175050-dcc7a225178d // indirect
- github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20210820175050-dcc7a225178d // indirect
+ github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220217153004-1622c70e5767 // indirect
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a // indirect
github.com/kawamuray/jsonpath v0.0.0-20201211160320-7483bafabd7e // indirect
github.com/kilic/bls12-381 v0.1.1-0.20210503002446-7b7597926c69 // indirect
diff --git a/cmd/aries-js-worker/go.sum b/cmd/aries-js-worker/go.sum
index 7f3afd596..388776c01 100644
--- a/cmd/aries-js-worker/go.sum
+++ b/cmd/aries-js-worker/go.sum
@@ -184,8 +184,9 @@ github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKe
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210820153043-8b6f36d10ab9/go.mod h1:7jEZdg455syX4f+ozLgwhYfIuiEQ/TgdIoOyALMwPG0=
-github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210820175050-dcc7a225178d h1:6n55F8lsCR2OGGZ+3RB2ppXkdmtVaoTV7MoTvpFRyTg=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210820175050-dcc7a225178d/go.mod h1:7jEZdg455syX4f+ozLgwhYfIuiEQ/TgdIoOyALMwPG0=
+github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220217153004-1622c70e5767 h1:XyfULUaaWSj+JRaILaxTUHFh0CujzODJ5P4qJNjZM+w=
+github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220217153004-1622c70e5767/go.mod h1:HojN6OAh8ZtXBe5X2arcSOe1SLo5Dsjqto8ICjSLQ2g=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
@@ -198,6 +199,7 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/kawamuray/jsonpath v0.0.0-20201211160320-7483bafabd7e h1:Eh/0JuXDdcBHc39j4tFXKTy/AKiK7IQkGJXQxyryXiU=
github.com/kawamuray/jsonpath v0.0.0-20201211160320-7483bafabd7e/go.mod h1:dz00yqWNWlKa9ff7RJzpnHPAPUazsid3yhVzXcsok94=
+github.com/kilic/bls12-381 v0.0.0-20201104083100-a288617c07f1/go.mod h1:gcwDl9YLyNc3H3wmPXamu+8evD8TYUa6BjTsWnvdn7A=
github.com/kilic/bls12-381 v0.1.1-0.20210503002446-7b7597926c69 h1:kMJlf8z8wUcpyI+FQJIdGjAhfTww1y0AbQEv86bpVQI=
github.com/kilic/bls12-381 v0.1.1-0.20210503002446-7b7597926c69/go.mod h1:tlkavyke+Ac7h8R3gZIjI5LKBcvMlSWnXNMgT3vZXo8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
@@ -244,6 +246,7 @@ github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
+github.com/piprate/json-gold v0.4.0/go.mod h1:OK1z7UgtBZk06n2cDE2OSq1kffmjFFp5/2yhLLCz9UM=
github.com/piprate/json-gold v0.4.1-0.20210813112359-33b90c4ca86c h1:F4YQvOA7UTccz06y59KLw4C0iXD28hnKUP9R9zeSe8U=
github.com/piprate/json-gold v0.4.1-0.20210813112359-33b90c4ca86c/go.mod h1:OK1z7UgtBZk06n2cDE2OSq1kffmjFFp5/2yhLLCz9UM=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@@ -270,6 +273,7 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/teserakt-io/golang-ed25519 v0.0.0-20200315192543-8255be791ce4/go.mod h1:9PdLyPiZIiW3UopXyRnPYyjUXSpiQNHRLu8fOsR3o8M=
github.com/teserakt-io/golang-ed25519 v0.0.0-20210104091850-3888c087a4c8 h1:RBkacARv7qY5laaXGlF4wFB/tk5rnthhPb8oIBGoagY=
github.com/teserakt-io/golang-ed25519 v0.0.0-20210104091850-3888c087a4c8/go.mod h1:9PdLyPiZIiW3UopXyRnPYyjUXSpiQNHRLu8fOsR3o8M=
github.com/tidwall/gjson v1.6.7 h1:Mb1M9HZCRWEcXQ8ieJo7auYyyiSux6w9XN3AdTpxJrE=
@@ -398,6 +402,7 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191025090151-53bf42e6b339/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -416,6 +421,7 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201211090839-8ad439b19e0f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=
diff --git a/component/storage/edv/batchencryptedformatter_test.go b/component/storage/edv/batchencryptedformatter_test.go
new file mode 100644
index 000000000..04315e2b8
--- /dev/null
+++ b/component/storage/edv/batchencryptedformatter_test.go
@@ -0,0 +1,366 @@
+/*
+Copyright SecureKey Technologies Inc. All Rights Reserved.
+
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package edv_test
+
+import (
+ "encoding/base64"
+ "encoding/json"
+ "fmt"
+ "testing"
+
+ "github.com/btcsuite/btcutil/base58"
+ "github.com/stretchr/testify/require"
+
+ "github.com/hyperledger/aries-framework-go/component/storage/edv"
+ "github.com/hyperledger/aries-framework-go/component/storageutil/formattedstore"
+ "github.com/hyperledger/aries-framework-go/component/storageutil/mem"
+ cryptoapi "github.com/hyperledger/aries-framework-go/pkg/crypto"
+ "github.com/hyperledger/aries-framework-go/pkg/doc/jose"
+ "github.com/hyperledger/aries-framework-go/pkg/kms"
+ spi "github.com/hyperledger/aries-framework-go/spi/storage"
+ storagetest "github.com/hyperledger/aries-framework-go/test/component/storage"
+)
+
+func TestBatchEncrypter_FormatDeformat(t *testing.T) {
+ tests := []struct {
+ name string
+ perfCrypto edv.PerfCrypto
+ expectedError string
+ }{
+ {
+ name: "test valid perf crypto formatting",
+ },
+ {
+ name: "test invalid perf crypto formatting",
+ perfCrypto: &testBadPerfCrypto{
+ batchCryptoErr: fmt.Errorf("bad batch crypto"),
+ },
+ expectedError: "edv encryption failed to compute mac and encrypt: bad batch crypto",
+ },
+ {
+ name: "test invalid perf crypto payload encoding",
+ perfCrypto: &testBadPerfCrypto{
+ batchCryptoVal: &edv.BatchCryptoPayload{
+ DocPayload: "badBase64Payload!#",
+ },
+ },
+ expectedError: "edv encryption can't decode document: illegal base64 data at input byte 16",
+ },
+ {
+ name: "test invalid perf crypto payload encoding",
+ perfCrypto: &testBadPerfCrypto{
+ batchCryptoVal: &edv.BatchCryptoPayload{
+ DocPayload: base64.RawURLEncoding.EncodeToString([]byte("payload")),
+ DocID: "badBase64DocID!#",
+ },
+ },
+ expectedError: "edv encryption can't decode docID: illegal base64 data at input byte 14",
+ },
+ }
+
+ for _, tt := range tests {
+ tc := tt
+
+ t.Run("test valid perf crypto formatting", func(t *testing.T) {
+ isValidPerf := tc.perfCrypto == nil
+ formatter := createValidBatchEncryptedFormatter(t, isValidPerf, tc.perfCrypto,
+ edv.WithDeterministicDocumentIDs())
+
+ docID, protectedDoc, tags, err := formatter.Format("test-key", []byte("doc-payload"), spi.Tag{
+ Name: "tag1",
+ Value: "tagValue1",
+ }, spi.Tag{
+ Name: "tag2",
+ Value: "tagValue2",
+ })
+
+ if isValidPerf {
+ require.NoError(t, err)
+ require.NotEmpty(t, docID)
+ require.NotEmpty(t, protectedDoc)
+ require.NotEmpty(t, tags)
+ } else {
+ require.EqualError(t, err, tc.expectedError)
+ require.Empty(t, docID)
+ require.Empty(t, protectedDoc)
+ require.Empty(t, tags)
+ }
+ })
+ }
+
+ formatter := createValidBatchEncryptedFormatter(t, true, nil,
+ edv.WithDeterministicDocumentIDs())
+
+ provider := formattedstore.NewProvider(mem.NewProvider(), formatter)
+ require.NotNil(t, provider)
+
+ storagetest.TestAll(t, provider, storagetest.SkipSortTests(false))
+}
+
+func createValidBatchEncryptedFormatter(t *testing.T, isValidCrypto bool, perfCrypto edv.PerfCrypto,
+ options ...edv.EncryptedFormatterOption) *edv.EncryptedFormatter {
+ kmsSvc, cryptoSvc := createKMSAndCrypto(t)
+ encrypter, decrypter, kid := createEncrypterAndDecrypter(t, kmsSvc, cryptoSvc)
+
+ encKH, err := kmsSvc.Get(kid)
+ require.NoError(t, err)
+
+ _, macKH, err := kmsSvc.Create(kms.HMACSHA256Tag256Type)
+ require.NoError(t, err)
+
+ if isValidCrypto {
+ perfCrypto = &testValidPerfCrypto{
+ jweEncrypter: encrypter,
+ jweDecrypter: decrypter,
+ km: kmsSvc,
+ crypto: cryptoSvc,
+ }
+ }
+
+ ebc := edv.NewBatchCrypto(macKH, encKH, perfCrypto)
+
+ formatter := edv.NewEncryptedFormatter(encrypter, decrypter, edv.NewMACCrypto(macKH, cryptoSvc),
+ append(options, edv.WithEDVBatchCrypto(ebc))...)
+ require.NotNil(t, formatter)
+
+ return formatter
+}
+
+type testBadPerfCrypto struct {
+ batchCryptoVal *edv.BatchCryptoPayload
+ batchCryptoErr error
+}
+
+// BatchCrypto computes all the MACs and EDV encryptions necessary by a KMS/crypto instance. This is an invalid mock
+// implementation.
+func (e *testBadPerfCrypto) BatchCrypto(_ *edv.BatchCryptoPayload, _, _ interface{}) (*edv.BatchCryptoPayload, error) {
+ return e.batchCryptoVal, e.batchCryptoErr
+}
+
+type testValidPerfCrypto struct {
+ jweEncrypter *jose.JWEEncrypt
+ jweDecrypter *jose.JWEDecrypt
+ km kms.KeyManager
+ crypto cryptoapi.Crypto
+}
+
+// BatchCrypto computes all the MACs and EDV encryptions necessary by a KMS/crypto instance. It is mocking server batch
+// crypto operations locally. Encryption KH is not used in this implementation since it already uses the JWEEncrypter
+// and JWEDecrypter that contain this KH pre loaded.
+func (e *testValidPerfCrypto) BatchCrypto(req *edv.BatchCryptoPayload, macKH,
+ _ interface{}) (*edv.BatchCryptoPayload, error) {
+ if req == nil {
+ return nil, fmt.Errorf("failed to ComputeCrypto: empty batch crypto request")
+ }
+
+ docID, err := e.generateDeterministicDocumentID(req.Prefix, req.DocID, macKH)
+ if err != nil {
+ return nil, err
+ }
+
+ docTags, err := e.formatTags(req.Prefix, req.DocTags, macKH)
+ if err != nil {
+ return nil, err
+ }
+
+ rawDoc, err := base64.RawURLEncoding.DecodeString(req.DocPayload)
+ if err != nil {
+ return nil, err
+ }
+
+ endDocument, err := e.formatValue(req.DocID, docID, rawDoc, req.DocTags, docTags)
+ if err != nil {
+ return nil, err
+ }
+
+ return &edv.BatchCryptoPayload{
+ Prefix: req.Prefix,
+ DocID: base64.RawURLEncoding.EncodeToString([]byte(docID)),
+ DocTags: docTags,
+ DocPayload: base64.RawURLEncoding.EncodeToString(endDocument),
+ }, nil
+}
+
+func (e *testValidPerfCrypto) generateDeterministicDocumentID(prefix, key string, macKH interface{}) (string, error) {
+ if key == "" {
+ return "", nil
+ }
+
+ keyHash, err := e.crypto.ComputeMAC([]byte(prefix+key), macKH)
+ if err != nil {
+ return "", fmt.Errorf(`failed to compute MAC based on key "%s": %w`, key, err)
+ }
+
+ return base58.Encode(keyHash[0:16]), nil
+}
+
+func (e *testValidPerfCrypto) formatTags(tagNamePrefix string, tags []spi.Tag, macKH interface{}) ([]spi.Tag, error) {
+ formattedTags := make([]spi.Tag, len(tags))
+
+ for i, tag := range tags {
+ formattedTag, err := e.formatTag(tagNamePrefix, tag, macKH)
+ if err != nil {
+ return nil, fmt.Errorf("failed to format tag: %w", err)
+ }
+
+ formattedTags[i] = formattedTag
+ }
+
+ return formattedTags, nil
+}
+
+func (e *testValidPerfCrypto) formatTag(tagNamePrefix string, tag spi.Tag, macKH interface{}) (spi.Tag, error) {
+ tagNameMAC, err := e.crypto.ComputeMAC([]byte(tagNamePrefix+tag.Name), macKH)
+ if err != nil {
+ return spi.Tag{}, fmt.Errorf(`failed to compute MAC for tag name "%s": %w`, tag.Name, err)
+ }
+
+ formattedTagName := base64.URLEncoding.EncodeToString(tagNameMAC)
+
+ var formattedTagValue string
+
+ if tag.Value != "" {
+ tagValueMAC, err := e.crypto.ComputeMAC([]byte(tag.Value), macKH)
+ if err != nil {
+ return spi.Tag{}, fmt.Errorf(`failed to compute MAC for tag value "%s": %w`, tag.Value, err)
+ }
+
+ formattedTagValue = base64.URLEncoding.EncodeToString(tagValueMAC)
+ }
+
+ return spi.Tag{
+ Name: formattedTagName,
+ Value: formattedTagValue,
+ }, nil
+}
+
+func (e *testValidPerfCrypto) formatValue(key, documentID string, value []byte,
+ tags, formattedTags []spi.Tag) ([]byte, error) {
+ var formattedValue []byte
+
+ if value != nil {
+ // Since the formatted key and tags are hashes and can't be reversed, the only way we can retrieve the
+ // unformatted key and tags later is to embed them in the structured document.
+ structuredDoc := createStructuredDocument(key, value, tags)
+
+ structuredDocumentBytes, err := json.Marshal(structuredDoc)
+ if err != nil {
+ return nil, fmt.Errorf(`failed to marshal structured document into bytes: %w`, err)
+ }
+
+ jwe, err := e.jweEncrypter.Encrypt(structuredDocumentBytes)
+ if err != nil {
+ return nil, fmt.Errorf(`failed to encrypt structured document bytes: %w`, err)
+ }
+
+ serializedJWE, err := jwe.FullSerialize(json.Marshal)
+ if err != nil {
+ return nil, fmt.Errorf(`failed to serialize JWE: %w`, err)
+ }
+
+ indexedAttributeCollections := e.convertToIndexedAttributeCollection(formattedTags)
+
+ encryptedDoc := encryptedDocument{
+ ID: documentID,
+ IndexedAttributeCollections: indexedAttributeCollections,
+ JWE: []byte(serializedJWE),
+ }
+
+ encryptedDocumentBytes, err := json.Marshal(encryptedDoc)
+ if err != nil {
+ return nil, fmt.Errorf("failed to marshal encrypted document into bytes: %w", err)
+ }
+
+ formattedValue = encryptedDocumentBytes
+ }
+
+ return formattedValue, nil
+}
+
+func createStructuredDocument(key string, value []byte, tags []spi.Tag) structuredDocument {
+ structuredDocumentContent := content{
+ UnformattedKey: key,
+ UnformattedValue: value,
+ }
+
+ if len(tags) != 0 {
+ structuredDocumentContent.UnformattedTags = tags
+ }
+
+ // In the spec, Structured Documents have IDs, but they don't really seem to serve
+ // any purpose - at least not for us.
+ // We will omit it for now. https://github.com/decentralized-identity/confidential-storage/issues/163
+ return structuredDocument{
+ Content: structuredDocumentContent,
+ }
+}
+
+func (e *testValidPerfCrypto) convertToIndexedAttributeCollection(
+ formattedTags []spi.Tag) []indexedAttributeCollection {
+ indexedAttributes := make([]indexedAttribute, len(formattedTags))
+
+ for i, formattedTag := range formattedTags {
+ indexedAttributes[i] = indexedAttribute{
+ Name: formattedTag.Name,
+ Value: formattedTag.Value,
+ }
+ }
+
+ indexedAttrCollection := indexedAttributeCollection{
+ HMAC: idTypePair{},
+ IndexedAttributes: indexedAttributes,
+ }
+
+ return []indexedAttributeCollection{indexedAttrCollection}
+}
+
+// structuredDocument represents a Structured Document for use with Aries. It's compatible with the model
+// defined in https://identity.foundation/confidential-storage/#structureddocument.
+type structuredDocument struct {
+ ID string `json:"id"`
+ Meta map[string]interface{} `json:"meta"`
+ Content content `json:"content"`
+}
+
+type content struct {
+ UnformattedKey string `json:"unformattedKey"`
+ UnformattedValue []byte `json:"unformattedValue"`
+ UnformattedTags []spi.Tag `json:"unformattedTags"`
+}
+
+// indexedAttributeCollection represents a collection of indexed attributes,
+// all of which share a common MAC algorithm and key.
+// This format is based on https://identity.foundation/confidential-storage/#creating-encrypted-indexes.
+type indexedAttributeCollection struct {
+ Sequence int `json:"sequence"`
+ HMAC idTypePair `json:"hmac"`
+ IndexedAttributes []indexedAttribute `json:"attributes"`
+}
+
+// indexedAttribute represents a single indexed attribute.
+type indexedAttribute struct {
+ Name string `json:"name"`
+ Value string `json:"value"`
+ Unique bool `json:"unique"`
+}
+
+// idTypePair represents an ID+Type pair.
+// TODO: #2262 This is a simplified version of the actual EDV query format, which is still not finalized
+// in the spec as of writing. See: https://github.com/decentralized-identity/confidential-storage/issues/34.
+type idTypePair struct {
+ ID string `json:"id"`
+ Type string `json:"type"`
+}
+
+// encryptedDocument represents an Encrypted Document as defined in
+// https://identity.foundation/confidential-storage/#encrypteddocument.
+type encryptedDocument struct {
+ ID string `json:"id"`
+ Sequence int `json:"sequence"`
+ IndexedAttributeCollections []indexedAttributeCollection `json:"indexed,omitempty"`
+ JWE json.RawMessage `json:"jwe"`
+}
diff --git a/component/storage/edv/encryptedformatter.go b/component/storage/edv/encryptedformatter.go
index ced3ea743..ddd079253 100644
--- a/component/storage/edv/encryptedformatter.go
+++ b/component/storage/edv/encryptedformatter.go
@@ -19,6 +19,8 @@ import (
spi "github.com/hyperledger/aries-framework-go/spi/storage"
)
+const edvIDSize = 16
+
// EncryptedFormatterOption allows for configuration of an EncryptedFormatter.
type EncryptedFormatterOption func(opts *EncryptedFormatter)
@@ -36,11 +38,21 @@ func WithDeterministicDocumentIDs() EncryptedFormatterOption {
}
}
+// WithEDVBatchCrypto adds support for executing MAC/JWE encryption and KeyWrapping in 1 batch call on a remote KMS
+// server. If set, then the default Encryption and MACCrypto calls during format() will not be executed locally.
+// BatchCrypto handles these operations instead.
+func WithEDVBatchCrypto(batchCrypto *BatchCrypto) EncryptedFormatterOption {
+ return func(encryptedFormatter *EncryptedFormatter) {
+ encryptedFormatter.edvBatchCrypto = batchCrypto
+ }
+}
+
// EncryptedFormatter formats data for use with an Encrypted Data Vault.
type EncryptedFormatter struct {
jweEncrypter jose.Encrypter
jweDecrypter jose.Decrypter
macCrypto *MACCrypto
+ edvBatchCrypto *BatchCrypto
useDeterministicDocumentIDs bool
}
@@ -72,6 +84,10 @@ func NewEncryptedFormatter(jweEncrypter jose.Encrypter, jweDecrypter jose.Decryp
// EDV encrypted indexes, and turns key + value + tags into an encrypted document, which is then returned as the
// formatted value from this function.
func (e *EncryptedFormatter) Format(key string, value []byte, tags ...spi.Tag) (string, []byte, []spi.Tag, error) {
+ if e.edvBatchCrypto != nil {
+ return e.batchFormat("", key, value, tags...)
+ }
+
return e.format("", key, value, tags...)
}
@@ -138,6 +154,36 @@ func (e *EncryptedFormatter) format(keyAndTagPrefix, key string, value []byte, t
return documentID, formattedValue, formattedTags, nil
}
+func (e *EncryptedFormatter) batchFormat(tagNamePrefix, key string, value []byte, tags ...spi.Tag) (string,
+ []byte, []spi.Tag, error) {
+ edvReq := &BatchCryptoPayload{
+ DocID: tagNamePrefix + key,
+ DocTags: tags,
+ DocPayload: base64.RawURLEncoding.EncodeToString(value),
+ }
+
+ edvRes, err := e.edvBatchCrypto.ComputeCrypto(edvReq)
+ if err != nil {
+ return "", nil, nil, fmt.Errorf("edv encryption failed to compute mac and encrypt: %w", err)
+ }
+
+ formattedValue, err := base64.RawURLEncoding.DecodeString(edvRes.DocPayload)
+ if err != nil {
+ return "", nil, nil, fmt.Errorf("edv encryption can't decode document: %w", err)
+ }
+
+ docID, err := base64.RawURLEncoding.DecodeString(edvRes.DocID)
+ if err != nil {
+ return "", nil, nil, fmt.Errorf("edv encryption can't decode docID: %w", err)
+ }
+
+ if len(docID) >= edvIDSize {
+ return base58.Encode(docID[0:edvIDSize]), formattedValue, tags, nil
+ }
+
+ return string(docID), formattedValue, tags, nil
+}
+
func (e *EncryptedFormatter) getStructuredDocFromEncryptedDoc(
encryptedDocBytes []byte) (structuredDocument, error) {
var encryptedDocument encryptedDocument
@@ -179,11 +225,11 @@ func (e *EncryptedFormatter) generateDeterministicDocumentID(prefix, key string)
return "", fmt.Errorf(`failed to compute MAC based on key "%s": %w`, key, err)
}
- return base58.Encode(keyHash[0:16]), nil
+ return base58.Encode(keyHash[0:edvIDSize]), nil
}
func generateRandomDocumentID() (string, error) {
- randomBytes := make([]byte, 16)
+ randomBytes := make([]byte, edvIDSize)
_, err := rand.Read(randomBytes)
if err != nil {
diff --git a/component/storage/edv/encryptedformatter_test.go b/component/storage/edv/encryptedformatter_test.go
index 3e1b6ceb6..0020d02e6 100644
--- a/component/storage/edv/encryptedformatter_test.go
+++ b/component/storage/edv/encryptedformatter_test.go
@@ -6,11 +6,9 @@ SPDX-License-Identifier: Apache-2.0
package edv_test
import (
- "bytes"
"encoding/json"
"testing"
- "github.com/google/tink/go/keyset"
"github.com/stretchr/testify/require"
"github.com/hyperledger/aries-framework-go/component/storage/edv"
@@ -19,10 +17,12 @@ import (
"github.com/hyperledger/aries-framework-go/component/storageutil/mem"
cryptoapi "github.com/hyperledger/aries-framework-go/pkg/crypto"
"github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto"
- "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite/ecdh"
- "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite/keyio"
"github.com/hyperledger/aries-framework-go/pkg/doc/jose"
+ "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"
storagetest "github.com/hyperledger/aries-framework-go/test/component/storage"
)
@@ -87,7 +87,8 @@ func TestEncryptedFormatter_Deformat(t *testing.T) {
}
func createValidEncryptedFormatter(t *testing.T, options ...edv.EncryptedFormatterOption) *edv.EncryptedFormatter {
- encrypter, decrypter := createEncrypterAndDecrypter(t)
+ kmsSvc, cryptoSvc := createKMSAndCrypto(t)
+ encrypter, decrypter, _ := createEncrypterAndDecrypter(t, kmsSvc, cryptoSvc)
formatter := edv.NewEncryptedFormatter(encrypter, decrypter, createValidMACCrypto(t),
options...)
@@ -96,29 +97,25 @@ func createValidEncryptedFormatter(t *testing.T, options ...edv.EncryptedFormatt
return formatter
}
-func createEncrypterAndDecrypter(t *testing.T) (*jose.JWEEncrypt, *jose.JWEDecrypt) {
- cryptoSvc, err := tinkcrypto.New()
- require.NoError(t, err)
-
- keyHandle, err := keyset.NewHandle(ecdh.NISTP256ECDHKWKeyTemplate())
+func createKMSAndCrypto(t *testing.T) (kms.KeyManager, cryptoapi.Crypto) {
+ p := mockkms.NewProviderForKMS(storage.NewMockStoreProvider(), &noop.NoLock{})
+ kmsSvc, err := localkms.New("local-lock://test/master/key/", p)
require.NoError(t, err)
- kmsSvc := &mockkms.KeyManager{
- GetKeyValue: keyHandle,
- }
-
- pubKH, err := keyHandle.Public()
+ cryptoSvc, err := tinkcrypto.New()
require.NoError(t, err)
- buf := new(bytes.Buffer)
- pubKeyWriter := keyio.NewWriter(buf)
+ return kmsSvc, cryptoSvc
+}
- err = pubKH.WriteWithNoSecrets(pubKeyWriter)
+func createEncrypterAndDecrypter(t *testing.T, kmsSvc kms.KeyManager,
+ cryptoSvc cryptoapi.Crypto) (*jose.JWEEncrypt, *jose.JWEDecrypt, string) {
+ kid, ecPubKeyBytes, err := kmsSvc.CreateAndExportPubKeyBytes(kms.NISTP256ECDHKWType)
require.NoError(t, err)
ecPubKey := new(cryptoapi.PublicKey)
- err = json.Unmarshal(buf.Bytes(), ecPubKey)
+ err = json.Unmarshal(ecPubKeyBytes, ecPubKey)
require.NoError(t, err)
encrypter, err := jose.NewJWEEncrypt(jose.A256GCM, "application/JSON",
@@ -127,5 +124,5 @@ func createEncrypterAndDecrypter(t *testing.T) (*jose.JWEEncrypt, *jose.JWEDecry
decrypter := jose.NewJWEDecrypt(nil, cryptoSvc, kmsSvc)
- return encrypter, decrypter
+ return encrypter, decrypter, kid
}
diff --git a/component/storage/edv/go.mod b/component/storage/edv/go.mod
index 739c2d0c0..d69aa1be9 100644
--- a/component/storage/edv/go.mod
+++ b/component/storage/edv/go.mod
@@ -7,27 +7,32 @@ module github.com/hyperledger/aries-framework-go/component/storage/edv
go 1.17
require (
- github.com/btcsuite/btcutil v1.0.1
+ github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce
github.com/cenkalti/backoff/v4 v4.0.2
github.com/google/tink/go v1.6.1-0.20210519071714-58be99b3c4d0
github.com/google/uuid v1.1.2
- github.com/hyperledger/aries-framework-go v0.1.7-0.20210603210127-e57b8c94e3cf
- github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20210820175050-dcc7a225178d
- github.com/hyperledger/aries-framework-go/spi v0.0.0-20210820175050-dcc7a225178d
- github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210820175050-dcc7a225178d
+ github.com/hyperledger/aries-framework-go v0.1.8-0.20220217153004-1622c70e5767
+ github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220217153004-1622c70e5767
+ github.com/hyperledger/aries-framework-go/spi v0.0.0-20220217153004-1622c70e5767
+ github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220217153004-1622c70e5767
github.com/stretchr/testify v1.7.0
)
require (
- github.com/btcsuite/btcd v0.20.1-beta // indirect
+ github.com/btcsuite/btcd v0.22.0-beta // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
- github.com/golang/protobuf v1.5.0 // indirect
- github.com/kilic/bls12-381 v0.0.0-20201104083100-a288617c07f1 // indirect
+ github.com/golang/protobuf v1.5.2 // indirect
+ github.com/kilic/bls12-381 v0.1.1-0.20210503002446-7b7597926c69 // indirect
+ github.com/piprate/json-gold v0.4.1-0.20210813112359-33b90c4ca86c // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
+ github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect
github.com/square/go-jose/v3 v3.0.0-20200630053402-0a67ce9b0693 // indirect
- github.com/teserakt-io/golang-ed25519 v0.0.0-20200315192543-8255be791ce4 // indirect
- golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0 // indirect
- golang.org/x/sys v0.0.0-20201211090839-8ad439b19e0f // indirect
- google.golang.org/protobuf v1.26.0 // indirect
- gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
+ github.com/teserakt-io/golang-ed25519 v0.0.0-20210104091850-3888c087a4c8 // indirect
+ github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
+ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
+ github.com/xeipuuv/gojsonschema v1.2.0 // indirect
+ golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e // indirect
+ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect
+ google.golang.org/protobuf v1.27.1 // indirect
+ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
)
diff --git a/component/storage/edv/go.sum b/component/storage/edv/go.sum
index 82be35ff6..c48b4c89a 100644
--- a/component/storage/edv/go.sum
+++ b/component/storage/edv/go.sum
@@ -46,15 +46,19 @@ github.com/aws/aws-sdk-go v1.35.7/go.mod h1:tlPOdRjfxPBpNIwqDj61rmsnA85v9jc0Ps9+
github.com/aws/aws-sdk-go v1.36.29/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bluele/gcache v0.0.0-20190518031135-bc40bd653833/go.mod h1:8c4/i2VlovMO2gBnHGQPN5EJw+H0lx1u/5p+cgsXtCk=
-github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw=
github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
+github.com/btcsuite/btcd v0.22.0-beta h1:LTDpDKUM5EeOFBPM8IXpinEcmZ6FWfNZbE3lfrfdnWo=
+github.com/btcsuite/btcd v0.22.0-beta/go.mod h1:9n5ntfhhHQBIhUvlhDvD3Qg6fRUj4jkN0VB8L8svzOA=
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
-github.com/btcsuite/btcutil v1.0.1 h1:GKOz8BnRjYrb/JTKgaOk+zh26NWNdSNvdvv0xoAZMSA=
github.com/btcsuite/btcutil v1.0.1/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts=
+github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce h1:YtWJF7RHm2pYCvA5t0RPmAaLUhREsKuKd+SLhxFbFeQ=
+github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o=
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg=
github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY=
+github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I=
github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
+github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY=
github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
github.com/cenkalti/backoff/v4 v4.0.2 h1:JIufpQLbh4DkbQoii76ItQIUFzevQSqOLZca4eamEDs=
@@ -70,6 +74,7 @@ github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
@@ -95,6 +100,7 @@ github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFU
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
+github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@@ -110,8 +116,9 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
-github.com/golang/protobuf v1.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
+github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
+github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
@@ -167,14 +174,18 @@ github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKe
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/hyperledger/aries-framework-go v0.1.7-0.20210421203733-b5dfd703a8fc/go.mod h1:tBgxVOKcNero3QI21iNf3oxxHkgRMDOby937cqHEvW4=
-github.com/hyperledger/aries-framework-go v0.1.7-0.20210603210127-e57b8c94e3cf h1:sN576g+pFSf/lKIbsb/VhhuFXdYxUFe6RO6Ls1qKwCU=
github.com/hyperledger/aries-framework-go v0.1.7-0.20210603210127-e57b8c94e3cf/go.mod h1:h6L+YoXtw90OZrH2IequxukIGwzfSpz8pUueQ9T5KqI=
+github.com/hyperledger/aries-framework-go v0.1.8-0.20220217153004-1622c70e5767 h1:F/yxXrzPB1T2nawE4u3Wcu3gHVcNbTY/aUV8kqfk8r4=
+github.com/hyperledger/aries-framework-go v0.1.8-0.20220217153004-1622c70e5767/go.mod h1:rBMOJVwyHyYbOqbb3IB/ExBkHyvFLht/W81s24GmjcE=
github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20210520055214-ae429bb89bf7/go.mod h1:7D+Y5J9cIsUrMGFAsIED+3bAPNjxp6ggXo0/kT5N6BI=
+github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20210820175050-dcc7a225178d/go.mod h1:i40JkMHCh9cHHxSc1SYznO3xDH6ly5CE0B3vPYZVeWI=
github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20210409151411-eeeb8508bd87/go.mod h1:kJT7bcaKsvk1lMp2jqS8srF+ZUie2H4MoPbL2V29dgA=
github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20210421203733-b5dfd703a8fc/go.mod h1:uGc7F3tXQIY6xjs8VEI6/oxp4ZDXDfGjPMCTgax5Zhc=
github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20210520055214-ae429bb89bf7/go.mod h1:aP6VnxeSbmD1OcV2f8y0dRV9fkIZp/+mzmgKxxmSJG4=
-github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20210820175050-dcc7a225178d h1:x9znF6oDcA2Q8L1Ud2TlNve//DRX4z380J3KMJ/xJ30=
+github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20210807121559-b41545a4f1e8/go.mod h1:k8CjDLBLxygTEj3D077OeH4SJsVE3mK60AyeO/C9sxs=
github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20210820175050-dcc7a225178d/go.mod h1:wdgGPwXzih+QD2Q4nvMnGO0dm0D0rxmzQcSNLcW6fcg=
+github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220217153004-1622c70e5767 h1:BX1LZzhs9ONfxMPSPQPhXuXQllJSYO7DjrQ0w2uxJHo=
+github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220217153004-1622c70e5767/go.mod h1:yLgRpVlZ2heeeOpTgvEnG/yHL9q1keUu5ILQ6s2qpLU=
github.com/hyperledger/aries-framework-go/spi v0.0.0-20210320144851-40976de98ccf/go.mod h1:fDr9wW00GJJl1lR1SFHmJW8utIocdvjO5RNhAYS05EY=
github.com/hyperledger/aries-framework-go/spi v0.0.0-20210322152545-e6ebe2c79a2a/go.mod h1:fDr9wW00GJJl1lR1SFHmJW8utIocdvjO5RNhAYS05EY=
github.com/hyperledger/aries-framework-go/spi v0.0.0-20210409151411-eeeb8508bd87/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
@@ -182,19 +193,27 @@ github.com/hyperledger/aries-framework-go/spi v0.0.0-20210412201938-efffe3eafcd1
github.com/hyperledger/aries-framework-go/spi v0.0.0-20210421165342-de8f911415e3/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
github.com/hyperledger/aries-framework-go/spi v0.0.0-20210421203733-b5dfd703a8fc/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
github.com/hyperledger/aries-framework-go/spi v0.0.0-20210520055214-ae429bb89bf7/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
+github.com/hyperledger/aries-framework-go/spi v0.0.0-20210603134946-53276bbf0c28/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
+github.com/hyperledger/aries-framework-go/spi v0.0.0-20210603182844-353ecb34cf4d/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
github.com/hyperledger/aries-framework-go/spi v0.0.0-20210806210220-65863dbe349a/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
github.com/hyperledger/aries-framework-go/spi v0.0.0-20210807121559-b41545a4f1e8/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
github.com/hyperledger/aries-framework-go/spi v0.0.0-20210818133831-4e22573c126d/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
-github.com/hyperledger/aries-framework-go/spi v0.0.0-20210820175050-dcc7a225178d h1:0JfPT4ORTdFMQknng3TiA2G/YY80+AMmty/47K7z4Rw=
+github.com/hyperledger/aries-framework-go/spi v0.0.0-20210820153043-8b6f36d10ab9/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
github.com/hyperledger/aries-framework-go/spi v0.0.0-20210820175050-dcc7a225178d/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
+github.com/hyperledger/aries-framework-go/spi v0.0.0-20211203210130-e927c9ed581a/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
+github.com/hyperledger/aries-framework-go/spi v0.0.0-20220217153004-1622c70e5767 h1:sgn8Oplz12s0YMheYRXYedeBW9lJXh8/MUdWCrADx0c=
+github.com/hyperledger/aries-framework-go/spi v0.0.0-20220217153004-1622c70e5767/go.mod h1:4bD5c5fj5K7rkQurVa/8I8+TfNcI4bxIBzaUNcxTOTg=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210324232048-34ff560ed041/go.mod h1:eKGEEe+PJNDQo7kVif3sUKBWwnsQDkE3gD/QlpmukcQ=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210409151411-eeeb8508bd87/go.mod h1:JHzDtgJLd0134iLFXLxGBjJF+Z+TgiElA/5oVgMazts=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210421203733-b5dfd703a8fc/go.mod h1:asiCVCtH/nocWKhZRMz12aFgdUh8lRHqKis0M8Ei/4I=
+github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210603182844-353ecb34cf4d/go.mod h1:J0SlvlnETEdYojUW4om/UINH0Uobmbtw46cH4DGXv5g=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210807121559-b41545a4f1e8/go.mod h1:3idbNcBl2wdRaETayzpY95KK5SfSzwXb5uqLW/Ldh0g=
-github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210820175050-dcc7a225178d h1:6n55F8lsCR2OGGZ+3RB2ppXkdmtVaoTV7MoTvpFRyTg=
-github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210820175050-dcc7a225178d/go.mod h1:7jEZdg455syX4f+ozLgwhYfIuiEQ/TgdIoOyALMwPG0=
+github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210820153043-8b6f36d10ab9/go.mod h1:7jEZdg455syX4f+ozLgwhYfIuiEQ/TgdIoOyALMwPG0=
+github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220217153004-1622c70e5767 h1:XyfULUaaWSj+JRaILaxTUHFh0CujzODJ5P4qJNjZM+w=
+github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220217153004-1622c70e5767/go.mod h1:HojN6OAh8ZtXBe5X2arcSOe1SLo5Dsjqto8ICjSLQ2g=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
+github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a/go.mod h1:yL958EeXv8Ylng6IfnvG4oflryUi3vgA3xPs9hmII1s=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
@@ -202,8 +221,9 @@ github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlT
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/kawamuray/jsonpath v0.0.0-20201211160320-7483bafabd7e/go.mod h1:dz00yqWNWlKa9ff7RJzpnHPAPUazsid3yhVzXcsok94=
-github.com/kilic/bls12-381 v0.0.0-20201104083100-a288617c07f1 h1:fLyvBx6b/VrqcC1KlgTsPdpX3BcwGRWV8P6QfdgOLuw=
github.com/kilic/bls12-381 v0.0.0-20201104083100-a288617c07f1/go.mod h1:gcwDl9YLyNc3H3wmPXamu+8evD8TYUa6BjTsWnvdn7A=
+github.com/kilic/bls12-381 v0.1.1-0.20210503002446-7b7597926c69 h1:kMJlf8z8wUcpyI+FQJIdGjAhfTww1y0AbQEv86bpVQI=
+github.com/kilic/bls12-381 v0.1.1-0.20210503002446-7b7597926c69/go.mod h1:tlkavyke+Ac7h8R3gZIjI5LKBcvMlSWnXNMgT3vZXo8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
github.com/klauspost/compress v1.10.0/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
@@ -223,6 +243,7 @@ github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrk
github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
+github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8=
@@ -234,14 +255,18 @@ github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXS
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/piprate/json-gold v0.4.0/go.mod h1:OK1z7UgtBZk06n2cDE2OSq1kffmjFFp5/2yhLLCz9UM=
+github.com/piprate/json-gold v0.4.1-0.20210813112359-33b90c4ca86c h1:F4YQvOA7UTccz06y59KLw4C0iXD28hnKUP9R9zeSe8U=
+github.com/piprate/json-gold v0.4.1-0.20210813112359-33b90c4ca86c/go.mod h1:OK1z7UgtBZk06n2cDE2OSq1kffmjFFp5/2yhLLCz9UM=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
+github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 h1:J9b7z+QKAmPf4YLrFg6oQUotqHQeUNWwkvo7jZp1GLU=
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
@@ -258,15 +283,19 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/teserakt-io/golang-ed25519 v0.0.0-20200315192543-8255be791ce4 h1:Sq/68UWgBzKT+pLTUTkSf0jS2IUwwXLFlZmeh+nAzQM=
github.com/teserakt-io/golang-ed25519 v0.0.0-20200315192543-8255be791ce4/go.mod h1:9PdLyPiZIiW3UopXyRnPYyjUXSpiQNHRLu8fOsR3o8M=
+github.com/teserakt-io/golang-ed25519 v0.0.0-20210104091850-3888c087a4c8 h1:RBkacARv7qY5laaXGlF4wFB/tk5rnthhPb8oIBGoagY=
+github.com/teserakt-io/golang-ed25519 v0.0.0-20210104091850-3888c087a4c8/go.mod h1:9PdLyPiZIiW3UopXyRnPYyjUXSpiQNHRLu8fOsR3o8M=
github.com/tidwall/gjson v1.6.7/go.mod h1:zeFuBCIqD4sN/gmqBzZ4j7Jd6UcA2Fc56x7QFsv+8fI=
github.com/tidwall/match v1.0.3/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.0.2/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/tidwall/sjson v1.1.4/go.mod h1:wXpKXu8CtDjKAZ+3DrKY5ROCorDFahq8l0tey/Lx1fg=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
+github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
+github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
+github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
@@ -286,9 +315,11 @@ golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0 h1:hb9wdF1z5waM+dSIICn1l0DkLVDT3hqhhQsDNUmHPRE=
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e h1:gsTQYXdTw2Gq7RBsWvlQ91b+aEQ6bXFUngBGuR8sPpI=
+golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -319,6 +350,7 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -347,6 +379,7 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -393,8 +426,13 @@ golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20201211090839-8ad439b19e0f h1:QdHQnPce6K4XQewki9WNbG5KOROuDzqO3NaYjI1cXJ0=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201211090839-8ad439b19e0f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=
+golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -530,8 +568,9 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
-google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
+google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
+google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
@@ -543,8 +582,9 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
+gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
diff --git a/component/storage/edv/maccrypto.go b/component/storage/edv/maccrypto.go
index 8f530f204..e8c41cf6b 100644
--- a/component/storage/edv/maccrypto.go
+++ b/component/storage/edv/maccrypto.go
@@ -6,6 +6,8 @@ SPDX-License-Identifier: Apache-2.0
package edv
+import spi "github.com/hyperledger/aries-framework-go/spi/storage"
+
// MACDigester represents a type that can compute MACs.
type MACDigester interface {
ComputeMAC(data []byte, kh interface{}) ([]byte, error)
@@ -29,3 +31,37 @@ func NewMACCrypto(kh interface{}, macDigester MACDigester) *MACCrypto {
macDigester: macDigester,
}
}
+
+// PerfCrypto is used for computing all MAC and JWE encryption+KW in one call for performance optimization.
+type PerfCrypto interface {
+ BatchCrypto(req *BatchCryptoPayload, macKH, encKH interface{}) (*BatchCryptoPayload, error)
+}
+
+// BatchCryptoPayload struct represents a type that contains tags and document payloads for MACs and EDV encryption.
+type BatchCryptoPayload struct {
+ Prefix string `json:"Prefix,omitempty"`
+ DocID string `json:"DocID"`
+ DocTags []spi.Tag `json:"DocTags,omitempty"`
+ DocPayload string `json:"DocPayload"`
+}
+
+// BatchCrypto is used for computing all EDV cryptos.
+type BatchCrypto struct {
+ macKH interface{}
+ kwKH interface{}
+ perfCrypto PerfCrypto
+}
+
+// ComputeCrypto computes all the MACs and EDV encryptions necessary by a KMS instance.
+func (e *BatchCrypto) ComputeCrypto(req *BatchCryptoPayload) (*BatchCryptoPayload, error) {
+ return e.perfCrypto.BatchCrypto(req, e.macKH, e.kwKH)
+}
+
+// NewBatchCrypto compute MACs and EDV encrypt payloads.
+func NewBatchCrypto(macKH, kwKH interface{}, performanceCrypto PerfCrypto) *BatchCrypto {
+ return &BatchCrypto{
+ macKH: macKH,
+ kwKH: kwKH,
+ perfCrypto: performanceCrypto,
+ }
+}
diff --git a/component/storage/edv/restprovider_test.go b/component/storage/edv/restprovider_test.go
index bac9c13ce..39af09be7 100644
--- a/component/storage/edv/restprovider_test.go
+++ b/component/storage/edv/restprovider_test.go
@@ -213,7 +213,8 @@ func TestRESTStore_Put(t *testing.T) {
func TestRESTStore_Get(t *testing.T) {
t.Run("Fail to decrypt encrypted document", func(t *testing.T) {
- encrypter, _ := createEncrypterAndDecrypter(t)
+ kmsSvc, cryptoSvc := createKMSAndCrypto(t)
+ encrypter, _, _ := createEncrypterAndDecrypter(t, kmsSvc, cryptoSvc)
failingEncryptedFormatter := edv.NewEncryptedFormatter(encrypter, &failingDecrypter{},
createValidMACCrypto(t), edv.WithDeterministicDocumentIDs())
@@ -252,7 +253,8 @@ func TestRESTStore_GetTags(t *testing.T) {
require.Nil(t, tags)
})
t.Run("Fail to decrypt encrypted document", func(t *testing.T) {
- encrypter, _ := createEncrypterAndDecrypter(t)
+ kmsSvc, cryptoSvc := createKMSAndCrypto(t)
+ encrypter, _, _ := createEncrypterAndDecrypter(t, kmsSvc, cryptoSvc)
failingEncryptedFormatter := edv.NewEncryptedFormatter(encrypter, &failingDecrypter{},
createValidMACCrypto(t))
diff --git a/scripts/start_edv_test_docker_images.sh b/scripts/start_edv_test_docker_images.sh
old mode 100644
new mode 100755
From 63c66fd17a4ebed52fed128db64f1ea06c75cda2 Mon Sep 17 00:00:00 2001
From: Firas Qutishat
Date: Wed, 2 Mar 2022 11:49:46 -0500
Subject: [PATCH 04/54] feat: add version id and version time to resolve DID
Signed-off-by: Firas Qutishat
---
pkg/vdr/httpbinding/resolver.go | 48 +++++++++++++++++++++++--
pkg/vdr/httpbinding/resolver_test.go | 52 ++++++++++++++++++++++++++++
2 files changed, 98 insertions(+), 2 deletions(-)
diff --git a/pkg/vdr/httpbinding/resolver.go b/pkg/vdr/httpbinding/resolver.go
index 8ca6ab4d2..fe5bf603b 100644
--- a/pkg/vdr/httpbinding/resolver.go
+++ b/pkg/vdr/httpbinding/resolver.go
@@ -19,7 +19,11 @@ import (
)
const (
- didLDJson = "application/did+ld+json"
+ // VersionIDOpt version id opt this option is not mandatory.
+ VersionIDOpt = "versionID"
+ // VersionTimeOpt version time opt this option is not mandatory.
+ VersionTimeOpt = "versionTime"
+ didLDJson = "application/did+ld+json"
)
// resolveDID makes DID resolution via HTTP.
@@ -60,7 +64,39 @@ func (v *VDR) resolveDID(uri string) ([]byte, error) {
}
// Read implements didresolver.DidMethod.Read interface (https://w3c-ccg.github.io/did-resolution/#resolving-input)
-func (v *VDR) Read(didID string, _ ...vdrapi.DIDMethodOption) (*did.DocResolution, error) {
+func (v *VDR) Read(didID string, opts ...vdrapi.DIDMethodOption) (*did.DocResolution, error) { //nolint: funlen,gocyclo
+ didMethodOpts := &vdrapi.DIDMethodOpts{Values: make(map[string]interface{})}
+
+ // Apply options
+ for _, opt := range opts {
+ opt(didMethodOpts)
+ }
+
+ versionID := ""
+ versionTime := ""
+
+ if didMethodOpts.Values[VersionIDOpt] != nil {
+ var ok bool
+
+ versionID, ok = didMethodOpts.Values[VersionIDOpt].(string)
+ if !ok {
+ return nil, fmt.Errorf("versionIDOpt is not string")
+ }
+ }
+
+ if didMethodOpts.Values[VersionTimeOpt] != nil {
+ var ok bool
+
+ versionTime, ok = didMethodOpts.Values[VersionTimeOpt].(string)
+ if !ok {
+ return nil, fmt.Errorf("versionIDOpt is not string")
+ }
+ }
+
+ if versionID != "" && versionTime != "" {
+ return nil, fmt.Errorf("versionID and versionTime can not set at same time")
+ }
+
reqURL, err := url.ParseRequestURI(v.endpointURL)
if err != nil {
return nil, fmt.Errorf("url parse request uri failed: %w", err)
@@ -68,6 +104,14 @@ func (v *VDR) Read(didID string, _ ...vdrapi.DIDMethodOption) (*did.DocResolutio
reqURL.Path = path.Join(reqURL.Path, didID)
+ if versionID != "" {
+ reqURL.RawQuery = fmt.Sprintf("versionId=%s", versionID)
+ }
+
+ if versionTime != "" {
+ reqURL.RawQuery = fmt.Sprintf("versionTime=%s", versionTime)
+ }
+
data, err := v.resolveDID(reqURL.String())
if err != nil {
return nil, err
diff --git a/pkg/vdr/httpbinding/resolver_test.go b/pkg/vdr/httpbinding/resolver_test.go
index a5d1a8d3e..64acf93dd 100644
--- a/pkg/vdr/httpbinding/resolver_test.go
+++ b/pkg/vdr/httpbinding/resolver_test.go
@@ -131,6 +131,58 @@ func TestRead_DIDDoc(t *testing.T) {
require.NoError(t, err)
require.Equal(t, didDoc.ID, gotDocument.DIDDocument.ID)
})
+
+ t.Run("test success version id", func(t *testing.T) {
+ testServer := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
+ require.Equal(t, "/did:example:334455?versionId=v1", req.URL.String())
+ res.Header().Add("Content-type", "application/did+ld+json")
+ res.WriteHeader(http.StatusOK)
+ _, err := res.Write([]byte(didResolutionData))
+ require.NoError(t, err)
+ }))
+
+ defer func() { testServer.Close() }()
+
+ resolver, err := New(testServer.URL)
+ require.NoError(t, err)
+ gotDocument, err := resolver.Read("did:example:334455", vdrapi.WithOption(VersionIDOpt, "v1"))
+ require.NoError(t, err)
+ didDoc, err := did.ParseDocument([]byte(doc))
+ require.NoError(t, err)
+ require.Equal(t, didDoc.ID, gotDocument.DIDDocument.ID)
+ })
+
+ t.Run("test set version id and version time", func(t *testing.T) {
+ resolver, err := New("https://localhost")
+ require.NoError(t, err)
+ _, err = resolver.Read("did:example:334455",
+ vdrapi.WithOption(VersionIDOpt, "v1"),
+ vdrapi.WithOption(VersionTimeOpt, "2021-05-10T17:00:00Z"))
+ require.Error(t, err)
+ require.Contains(t, err.Error(), "versionID and versionTime can not set at same time")
+ })
+
+ t.Run("test success version time", func(t *testing.T) {
+ testServer := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
+ require.Equal(t, "/did:example:334455?versionTime=2021-05-10T17:00:00Z", req.URL.String())
+ res.Header().Add("Content-type", "application/did+ld+json")
+ res.WriteHeader(http.StatusOK)
+ _, err := res.Write([]byte(didResolutionData))
+ require.NoError(t, err)
+ }))
+
+ defer func() { testServer.Close() }()
+
+ resolver, err := New(testServer.URL)
+ require.NoError(t, err)
+ gotDocument, err := resolver.Read("did:example:334455",
+ vdrapi.WithOption(VersionTimeOpt, "2021-05-10T17:00:00Z"))
+ require.NoError(t, err)
+ didDoc, err := did.ParseDocument([]byte(doc))
+ require.NoError(t, err)
+ require.Equal(t, didDoc.ID, gotDocument.DIDDocument.ID)
+ })
+
t.Run("test empty doc", func(t *testing.T) {
testServer := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
require.Equal(t, "/did:example:334455", req.URL.String())
From 031ac92d06f48d97e32129efcb10f1366bf7080b Mon Sep 17 00:00:00 2001
From: Firas Qutishat
Date: Thu, 3 Mar 2022 03:42:22 -0500
Subject: [PATCH 05/54] chore: add versionId to DocumentMetadata
Signed-off-by: Firas Qutishat
Signed-off-by: Andrii Holovko
---
pkg/doc/did/doc.go | 2 ++
1 file changed, 2 insertions(+)
diff --git a/pkg/doc/did/doc.go b/pkg/doc/did/doc.go
index 01a6603f1..fdbcde8e7 100644
--- a/pkg/doc/did/doc.go
+++ b/pkg/doc/did/doc.go
@@ -205,6 +205,8 @@ type Operations struct {
// DocumentMetadata document metadata.
type DocumentMetadata struct {
+ // VersionID is version ID key.
+ VersionID string `json:"versionId,omitempty"`
// Deactivated is deactivated flag key.
Deactivated bool `json:"deactivated,omitempty"`
// CanonicalID is canonical ID key.
From cef4516d327e2b6999aa057e29a4706bc434218d Mon Sep 17 00:00:00 2001
From: Rolson Quadras
Date: Fri, 4 Mar 2022 13:41:41 -0500
Subject: [PATCH 06/54] docs: remove outdated demo app link (#3194)
---
cmd/aries-agent-mobile/README.md | 4 ----
1 file changed, 4 deletions(-)
diff --git a/cmd/aries-agent-mobile/README.md b/cmd/aries-agent-mobile/README.md
index 29c10cc60..1633d6695 100644
--- a/cmd/aries-agent-mobile/README.md
+++ b/cmd/aries-agent-mobile/README.md
@@ -460,10 +460,6 @@ class AriesService {
-### 3.3. Demo apps
-
-For examples of mobile apps built with the aries-agent-mobile bindings, see [https://github.com/trustbloc/aries-examples](https://github.com/trustbloc/aries-examples).
-
## 4. Test
From c69023595015a4de06d13a1a1d0d48ced7655483 Mon Sep 17 00:00:00 2001
From: Filip Burlacu
Date: Mon, 7 Mar 2022 13:15:54 -0500
Subject: [PATCH 07/54] fix: create oobv2 inviter's connection record on v1
messages, with invitation ID
- add invitation ID to inviter's implicit didcomm v2 connection
- allow all non-didexchange messages to use didcomm v2 handlers
Signed-off-by: Filip Burlacu
---
pkg/didcomm/common/middleware/middleware.go | 24 +++++++------
.../common/middleware/middleware_test.go | 35 ++++++++++++++++---
.../inbound/inbound_message_handler.go | 8 +++--
pkg/framework/context/context_test.go | 6 ++--
4 files changed, 52 insertions(+), 21 deletions(-)
diff --git a/pkg/didcomm/common/middleware/middleware.go b/pkg/didcomm/common/middleware/middleware.go
index 1a2a1637c..abddc721f 100644
--- a/pkg/didcomm/common/middleware/middleware.go
+++ b/pkg/didcomm/common/middleware/middleware.go
@@ -85,15 +85,9 @@ func (h *DIDCommMessageMiddleware) HandleInboundMessage( // nolint:gocyclo,funle
msg didcomm.DIDCommMsgMap,
theirDID, myDID string,
) error {
- if isV2, err := didcomm.IsDIDCommV2(&msg); !isV2 || err != nil {
- return err
- }
-
// TODO: clean up connection record management across all the handler methods. Currently correct but messy.
-
// TODO: clean up some logic:
// - inbound invitation acceptance cannot be a rotation
-
// GetConnectionRecordByDIDs(myDID, theirDID)
// if no connection, create connection
rec, err := h.handleInboundInvitationAcceptance(theirDID, myDID)
@@ -101,6 +95,11 @@ func (h *DIDCommMessageMiddleware) HandleInboundMessage( // nolint:gocyclo,funle
return err
}
+ isV2, err := didcomm.IsDIDCommV2(&msg)
+ if !isV2 || err != nil {
+ return err
+ }
+
var updatedConnRec bool
// if they don't rotate: GetConnectionRecordByTheirDID(theirDID)
@@ -170,13 +169,15 @@ func (h *DIDCommMessageMiddleware) HandleOutboundMessage(msg didcomm.DIDCommMsgM
type invitationStub struct {
Type string `json:"type"`
+ ID string `json:"id"`
}
func (h *DIDCommMessageMiddleware) handleInboundInvitationAcceptance(senderDID, recipientDID string,
) (*connection.Record, error) {
didParsed, err := did.Parse(recipientDID)
if err != nil {
- return nil, fmt.Errorf("parsing inbound recipient DID: %w", err)
+ logger.Warnf("failed to parse inbound recipient DID: %s", err.Error())
+ return nil, nil
}
if didParsed.Method == peer.DIDMethod { // TODO any more exception cases like peer?
@@ -195,10 +196,10 @@ func (h *DIDCommMessageMiddleware) handleInboundInvitationAcceptance(senderDID,
}
rec, err := h.connStore.GetConnectionRecordByDIDs(recipientDID, senderDID)
- if !errors.Is(err, storage.ErrDataNotFound) {
- // either an error, or a record exists
- logger.Warnf("record present, or error=%v", err)
- return rec, err
+ if err == nil {
+ return rec, nil
+ } else if !errors.Is(err, storage.ErrDataNotFound) {
+ return rec, fmt.Errorf("failed to get connection record: %w", err)
}
// if we created an invitation with this DID, and have no connection, we create a connection.
@@ -207,6 +208,7 @@ func (h *DIDCommMessageMiddleware) handleInboundInvitationAcceptance(senderDID,
ConnectionID: uuid.New().String(),
MyDID: recipientDID,
TheirDID: senderDID,
+ InvitationID: inv.ID,
State: connection.StateNameCompleted,
Namespace: connection.MyNSPrefix,
MediaTypeProfiles: h.mediaTypeProfiles,
diff --git a/pkg/didcomm/common/middleware/middleware_test.go b/pkg/didcomm/common/middleware/middleware_test.go
index a8dfc59b9..94991ba76 100644
--- a/pkg/didcomm/common/middleware/middleware_test.go
+++ b/pkg/didcomm/common/middleware/middleware_test.go
@@ -303,12 +303,12 @@ func TestDIDRotator_HandleOutboundMessage(t *testing.T) {
}
func TestHandleInboundAccept(t *testing.T) {
- t.Run("fail: parse recipient DID", func(t *testing.T) {
+ t.Run("skip: failed to parse recipient DID", func(t *testing.T) {
h := createBlankDIDRotator(t)
- _, err := h.handleInboundInvitationAcceptance("", "")
- require.Error(t, err)
- require.Contains(t, err.Error(), "parsing inbound recipient DID")
+ rec, err := h.handleInboundInvitationAcceptance("", "")
+ require.NoError(t, err)
+ require.Nil(t, rec)
})
t.Run("skip: recipient DID is peer", func(t *testing.T) {
@@ -348,6 +348,33 @@ func TestHandleInboundAccept(t *testing.T) {
require.ErrorIs(t, err, expectedErr)
})
+ t.Run("fail: error reading connection", func(t *testing.T) {
+ h := createBlankDIDRotator(t)
+
+ expectedErr := fmt.Errorf("store get error")
+
+ var err error
+ h.connStore, err = connection.NewRecorder(&mockProvider{
+ storeProvider: mockstorage.NewCustomMockStoreProvider(
+ &mockstorage.MockStore{
+ Store: map[string]mockstorage.DBEntry{},
+ ErrQuery: expectedErr,
+ }),
+ })
+ require.NoError(t, err)
+
+ err = h.connStore.SaveOOBv2Invitation(myDID, invitationStub{
+ Type: oobV2Type,
+ })
+ require.NoError(t, err)
+
+ rec, err := h.handleInboundInvitationAcceptance(theirDID, myDID)
+ require.Nil(t, rec)
+ require.Error(t, err)
+ require.Contains(t, err.Error(), "failed to get connection record")
+ require.ErrorIs(t, err, expectedErr)
+ })
+
t.Run("skip: connection already exists between invitation DID and invitee DID", func(t *testing.T) {
h := createBlankDIDRotator(t)
diff --git a/pkg/didcomm/dispatcher/inbound/inbound_message_handler.go b/pkg/didcomm/dispatcher/inbound/inbound_message_handler.go
index 2ca8bb768..718309af8 100644
--- a/pkg/didcomm/dispatcher/inbound/inbound_message_handler.go
+++ b/pkg/didcomm/dispatcher/inbound/inbound_message_handler.go
@@ -108,6 +108,8 @@ func (handler *MessageHandler) HandleInboundEnvelope(envelope *transport.Envelop
return err
}
+ isDIDEx := (&didexchange.Service{}).Accept(msg.Type())
+
isV2, err := service.IsDIDCommV2(&msg)
if err != nil {
return err
@@ -124,11 +126,11 @@ func (handler *MessageHandler) HandleInboundEnvelope(envelope *transport.Envelop
return fmt.Errorf("handling inbound peer DID: %w", err)
}
- // if msg is a didcomm v2 message, do additional handling
- if isV2 {
+ // if msg is not a didexchange message, do additional handling
+ if !isDIDEx {
myDID, theirDID, err = handler.getDIDs(envelope, msg)
if err != nil {
- return fmt.Errorf("get DIDs for didcomm/v2 message: %w", err)
+ return fmt.Errorf("get DIDs for message: %w", err)
}
gotDIDs = true
diff --git a/pkg/framework/context/context_test.go b/pkg/framework/context/context_test.go
index f1190c779..459d485b7 100644
--- a/pkg/framework/context/context_test.go
+++ b/pkg/framework/context/context_test.go
@@ -269,12 +269,12 @@ func TestNewProvider(t *testing.T) {
inboundHandler := ctx.InboundMessageHandler()
- err = inboundHandler(&transport.Envelope{Message: []byte(`
+ err = inboundHandler(&transport.Envelope{Message: []byte(fmt.Sprintf(`
{
"@frameworkID": "5678876542345",
"@id": "12345",
- "@type": "valid-message-type"
- }`), FromKey: []byte("fromKey"), ToKey: []byte("toKey")})
+ "@type": "%s"
+ }`, didexchange.RequestMsgType)), FromKey: []byte("fromKey"), ToKey: []byte("toKey")})
require.NoError(t, err)
})
From 9b214dd293e3ad9f8b16be2561252d8e0a932a84 Mon Sep 17 00:00:00 2001
From: Baha Shaaban
Date: Wed, 9 Mar 2022 12:26:40 -0500
Subject: [PATCH 08/54] feat: expose key type in ExportPubKeyBytes()
This changes adds the kms.Keytype return value in ExportPubKeyBytes()
closes #3198
Signed-off-by: Baha Shaaban
---
cmd/aries-agent-mobile/go.mod | 10 +--
cmd/aries-agent-mobile/go.sum | 11 ++-
cmd/aries-agent-rest/go.mod | 10 +--
cmd/aries-agent-rest/go.sum | 9 +-
cmd/aries-js-worker/go.mod | 8 +-
go.mod | 6 +-
go.sum | 19 +++-
pkg/client/issuecredential/rfc0593/event.go | 2 +-
.../issuecredential/rfc0593/event_test.go | 3 +-
pkg/controller/rest/rfc0593/operation_test.go | 3 +-
.../composite/keyio/composite_key_export.go | 49 +++++++----
.../keyio/composite_key_export_import_test.go | 12 +--
.../protocol/decorator/decorator_test.go | 3 +-
.../protocol/didexchange/service_test.go | 3 +-
pkg/doc/presexch/api_test.go | 3 +-
.../ed25519signature2018/suite_crypto_test.go | 2 +-
.../jsonwebsignature2020/suite_crypto_test.go | 2 +-
.../internal/signer/crypto_signer.go | 2 +-
pkg/internal/gomocks/kms/mocks.gen.go | 7 +-
pkg/kms/api.go | 2 +-
pkg/kms/localkms/localkms.go | 24 ++---
pkg/kms/localkms/localkms_test.go | 17 ++--
pkg/kms/localkms/pubkey_writer.go | 87 +++++++++++++------
pkg/kms/webkms/remotekms.go | 9 +-
pkg/kms/webkms/remotekms_test.go | 24 ++---
pkg/mock/kms/mock_kms.go | 7 +-
pkg/wallet/storage.go | 2 +-
test/bdd/go.mod | 9 +-
test/bdd/go.sum | 4 +-
test/bdd/pkg/verifiable/verifiable_steps.go | 2 +-
test/bdd/pkg/webkms/webkms_steps.go | 2 +-
31 files changed, 218 insertions(+), 135 deletions(-)
diff --git a/cmd/aries-agent-mobile/go.mod b/cmd/aries-agent-mobile/go.mod
index b25c159e8..cd8597d9d 100644
--- a/cmd/aries-agent-mobile/go.mod
+++ b/cmd/aries-agent-mobile/go.mod
@@ -8,10 +8,10 @@ go 1.17
require (
github.com/google/uuid v1.1.2
- github.com/hyperledger/aries-framework-go v0.1.7-0.20210603210127-e57b8c94e3cf
- github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20210820175050-dcc7a225178d
- github.com/hyperledger/aries-framework-go/spi v0.0.0-20210820175050-dcc7a225178d
- github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210820175050-dcc7a225178d
+ github.com/hyperledger/aries-framework-go v0.1.8-0.20220217153004-1622c70e5767
+ github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220308060532-714cd5c18552
+ github.com/hyperledger/aries-framework-go/spi v0.0.0-20220308060532-714cd5c18552
+ github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220308060532-714cd5c18552
github.com/piprate/json-gold v0.4.1-0.20210813112359-33b90c4ca86c
github.com/stretchr/testify v1.7.0
nhooyr.io/websocket v1.8.3
@@ -31,7 +31,7 @@ require (
github.com/golang/snappy v0.0.1 // indirect
github.com/google/tink/go v1.6.1-0.20210519071714-58be99b3c4d0 // indirect
github.com/gorilla/mux v1.7.3 // indirect
- github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20210820175050-dcc7a225178d // indirect
+ github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220308060532-714cd5c18552 // indirect
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a // indirect
github.com/kawamuray/jsonpath v0.0.0-20201211160320-7483bafabd7e // indirect
github.com/kilic/bls12-381 v0.1.1-0.20210503002446-7b7597926c69 // indirect
diff --git a/cmd/aries-agent-mobile/go.sum b/cmd/aries-agent-mobile/go.sum
index 895ec3fff..2f312c07c 100644
--- a/cmd/aries-agent-mobile/go.sum
+++ b/cmd/aries-agent-mobile/go.sum
@@ -55,7 +55,6 @@ github.com/btcsuite/btcd v0.22.0-beta h1:LTDpDKUM5EeOFBPM8IXpinEcmZ6FWfNZbE3lfrf
github.com/btcsuite/btcd v0.22.0-beta/go.mod h1:9n5ntfhhHQBIhUvlhDvD3Qg6fRUj4jkN0VB8L8svzOA=
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
-github.com/btcsuite/btcutil v1.0.1/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts=
github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce h1:YtWJF7RHm2pYCvA5t0RPmAaLUhREsKuKd+SLhxFbFeQ=
github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o=
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg=
@@ -183,12 +182,12 @@ github.com/hashicorp/vault/sdk v0.1.13/go.mod h1:B+hVj7TpuQY1Y/GPbCpffmgd+tSEwvh
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
-github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20210820175050-dcc7a225178d h1:Rfp6yyS21vqaSxxudqYtxCQJawI7f0RUs5oBvKbfT4Q=
-github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20210820175050-dcc7a225178d/go.mod h1:i40JkMHCh9cHHxSc1SYznO3xDH6ly5CE0B3vPYZVeWI=
-github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210807121559-b41545a4f1e8/go.mod h1:3idbNcBl2wdRaETayzpY95KK5SfSzwXb5uqLW/Ldh0g=
+github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220308060532-714cd5c18552 h1:5z5ACTvbjydtD9d04Inki7gy8k1RatVqi6zhSIIE0f8=
+github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220308060532-714cd5c18552/go.mod h1:eIac5lubCy3tw6D0sTluM5U6Bw3inBwUfjX17o2U7PE=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210820153043-8b6f36d10ab9/go.mod h1:7jEZdg455syX4f+ozLgwhYfIuiEQ/TgdIoOyALMwPG0=
-github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210820175050-dcc7a225178d h1:6n55F8lsCR2OGGZ+3RB2ppXkdmtVaoTV7MoTvpFRyTg=
-github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210820175050-dcc7a225178d/go.mod h1:7jEZdg455syX4f+ozLgwhYfIuiEQ/TgdIoOyALMwPG0=
+github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220217153004-1622c70e5767/go.mod h1:HojN6OAh8ZtXBe5X2arcSOe1SLo5Dsjqto8ICjSLQ2g=
+github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220308060532-714cd5c18552 h1:R9aDLtYSbbHUmLJhmTHdskmzHEBZiWnFy5pHjv5Ryhk=
+github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220308060532-714cd5c18552/go.mod h1:HojN6OAh8ZtXBe5X2arcSOe1SLo5Dsjqto8ICjSLQ2g=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
diff --git a/cmd/aries-agent-rest/go.mod b/cmd/aries-agent-rest/go.mod
index 9cde99cc1..ac7894f44 100644
--- a/cmd/aries-agent-rest/go.mod
+++ b/cmd/aries-agent-rest/go.mod
@@ -9,10 +9,10 @@ go 1.17
require (
github.com/cenkalti/backoff/v4 v4.1.0
github.com/gorilla/mux v1.7.3
- github.com/hyperledger/aries-framework-go v0.1.7-0.20210603210127-e57b8c94e3cf
- github.com/hyperledger/aries-framework-go/component/storage/leveldb v0.0.0-20210819200955-992239f52706
- github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20210820175050-dcc7a225178d
- github.com/hyperledger/aries-framework-go/spi v0.0.0-20210820175050-dcc7a225178d
+ github.com/hyperledger/aries-framework-go v0.1.8-0.20220217153004-1622c70e5767
+ github.com/hyperledger/aries-framework-go/component/storage/leveldb v0.0.0-20220308060532-714cd5c18552
+ github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220308060532-714cd5c18552
+ github.com/hyperledger/aries-framework-go/spi v0.0.0-20220308060532-714cd5c18552
github.com/rs/cors v1.7.0
github.com/spf13/cobra v1.0.0
github.com/stretchr/testify v1.7.0
@@ -31,7 +31,7 @@ require (
github.com/golang/snappy v0.0.3 // indirect
github.com/google/tink/go v1.6.1-0.20210519071714-58be99b3c4d0 // indirect
github.com/google/uuid v1.1.2 // indirect
- github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20210820175050-dcc7a225178d // indirect
+ github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220308060532-714cd5c18552 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a // indirect
github.com/kawamuray/jsonpath v0.0.0-20201211160320-7483bafabd7e // indirect
diff --git a/cmd/aries-agent-rest/go.sum b/cmd/aries-agent-rest/go.sum
index 8c39f6ed1..4a2e1bfc3 100644
--- a/cmd/aries-agent-rest/go.sum
+++ b/cmd/aries-agent-rest/go.sum
@@ -61,7 +61,6 @@ github.com/btcsuite/btcd v0.22.0-beta h1:LTDpDKUM5EeOFBPM8IXpinEcmZ6FWfNZbE3lfrf
github.com/btcsuite/btcd v0.22.0-beta/go.mod h1:9n5ntfhhHQBIhUvlhDvD3Qg6fRUj4jkN0VB8L8svzOA=
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
-github.com/btcsuite/btcutil v1.0.1/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts=
github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce h1:YtWJF7RHm2pYCvA5t0RPmAaLUhREsKuKd+SLhxFbFeQ=
github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o=
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg=
@@ -215,12 +214,12 @@ github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKe
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
-github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20210820175050-dcc7a225178d h1:Rfp6yyS21vqaSxxudqYtxCQJawI7f0RUs5oBvKbfT4Q=
-github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20210820175050-dcc7a225178d/go.mod h1:i40JkMHCh9cHHxSc1SYznO3xDH6ly5CE0B3vPYZVeWI=
-github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210807121559-b41545a4f1e8/go.mod h1:3idbNcBl2wdRaETayzpY95KK5SfSzwXb5uqLW/Ldh0g=
+github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220308060532-714cd5c18552 h1:5z5ACTvbjydtD9d04Inki7gy8k1RatVqi6zhSIIE0f8=
+github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220308060532-714cd5c18552/go.mod h1:eIac5lubCy3tw6D0sTluM5U6Bw3inBwUfjX17o2U7PE=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210820153043-8b6f36d10ab9/go.mod h1:7jEZdg455syX4f+ozLgwhYfIuiEQ/TgdIoOyALMwPG0=
-github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210820175050-dcc7a225178d h1:6n55F8lsCR2OGGZ+3RB2ppXkdmtVaoTV7MoTvpFRyTg=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210820175050-dcc7a225178d/go.mod h1:7jEZdg455syX4f+ozLgwhYfIuiEQ/TgdIoOyALMwPG0=
+github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220217153004-1622c70e5767 h1:XyfULUaaWSj+JRaILaxTUHFh0CujzODJ5P4qJNjZM+w=
+github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220217153004-1622c70e5767/go.mod h1:HojN6OAh8ZtXBe5X2arcSOe1SLo5Dsjqto8ICjSLQ2g=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
diff --git a/cmd/aries-js-worker/go.mod b/cmd/aries-js-worker/go.mod
index 5b5e627c3..f7c697f20 100644
--- a/cmd/aries-js-worker/go.mod
+++ b/cmd/aries-js-worker/go.mod
@@ -8,9 +8,9 @@ go 1.17
require (
github.com/google/uuid v1.1.2
- github.com/hyperledger/aries-framework-go v0.1.8-0.20220217153004-1622c70e5767
+ github.com/hyperledger/aries-framework-go v0.1.8-0.20220308060532-714cd5c18552
github.com/hyperledger/aries-framework-go/component/storage/indexeddb v0.0.0-00010101000000-000000000000
- github.com/hyperledger/aries-framework-go/spi v0.0.0-20220217153004-1622c70e5767
+ github.com/hyperledger/aries-framework-go/spi v0.0.0-20220308060532-714cd5c18552
github.com/mitchellh/mapstructure v1.3.0
github.com/stretchr/testify v1.7.0
)
@@ -29,8 +29,8 @@ require (
github.com/golang/snappy v0.0.1 // indirect
github.com/google/tink/go v1.6.1-0.20210519071714-58be99b3c4d0 // indirect
github.com/gorilla/mux v1.7.3 // indirect
- github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20210820175050-dcc7a225178d // indirect
- github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220217153004-1622c70e5767 // indirect
+ github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220308060532-714cd5c18552 // indirect
+ github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220308060532-714cd5c18552 // indirect
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a // indirect
github.com/kawamuray/jsonpath v0.0.0-20201211160320-7483bafabd7e // indirect
github.com/kilic/bls12-381 v0.1.1-0.20210503002446-7b7597926c69 // indirect
diff --git a/go.mod b/go.mod
index ef8c5d86f..072c8ce35 100644
--- a/go.mod
+++ b/go.mod
@@ -17,9 +17,9 @@ require (
github.com/google/tink/go v1.6.1-0.20210519071714-58be99b3c4d0
github.com/google/uuid v1.1.2
github.com/gorilla/mux v1.7.3
- github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20210820175050-dcc7a225178d
- github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20210820175050-dcc7a225178d
- github.com/hyperledger/aries-framework-go/spi v0.0.0-20210820175050-dcc7a225178d
+ github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220308060532-714cd5c18552
+ github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220308060532-714cd5c18552
+ github.com/hyperledger/aries-framework-go/spi v0.0.0-20220308060532-714cd5c18552
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a
github.com/kawamuray/jsonpath v0.0.0-20201211160320-7483bafabd7e
github.com/kilic/bls12-381 v0.1.1-0.20210503002446-7b7597926c69
diff --git a/go.sum b/go.sum
index fdf55d392..479dda2cb 100644
--- a/go.sum
+++ b/go.sum
@@ -187,15 +187,19 @@ github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKe
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/hyperledger/aries-framework-go v0.1.7-0.20210421203733-b5dfd703a8fc/go.mod h1:tBgxVOKcNero3QI21iNf3oxxHkgRMDOby937cqHEvW4=
github.com/hyperledger/aries-framework-go v0.1.7-0.20210603210127-e57b8c94e3cf/go.mod h1:h6L+YoXtw90OZrH2IequxukIGwzfSpz8pUueQ9T5KqI=
+github.com/hyperledger/aries-framework-go v0.1.8-0.20220217153004-1622c70e5767/go.mod h1:rBMOJVwyHyYbOqbb3IB/ExBkHyvFLht/W81s24GmjcE=
github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20210520055214-ae429bb89bf7/go.mod h1:7D+Y5J9cIsUrMGFAsIED+3bAPNjxp6ggXo0/kT5N6BI=
-github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20210820175050-dcc7a225178d h1:Rfp6yyS21vqaSxxudqYtxCQJawI7f0RUs5oBvKbfT4Q=
github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20210820175050-dcc7a225178d/go.mod h1:i40JkMHCh9cHHxSc1SYznO3xDH6ly5CE0B3vPYZVeWI=
+github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220308060532-714cd5c18552 h1:5z5ACTvbjydtD9d04Inki7gy8k1RatVqi6zhSIIE0f8=
+github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220308060532-714cd5c18552/go.mod h1:eIac5lubCy3tw6D0sTluM5U6Bw3inBwUfjX17o2U7PE=
github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20210409151411-eeeb8508bd87/go.mod h1:kJT7bcaKsvk1lMp2jqS8srF+ZUie2H4MoPbL2V29dgA=
github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20210421203733-b5dfd703a8fc/go.mod h1:uGc7F3tXQIY6xjs8VEI6/oxp4ZDXDfGjPMCTgax5Zhc=
github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20210520055214-ae429bb89bf7/go.mod h1:aP6VnxeSbmD1OcV2f8y0dRV9fkIZp/+mzmgKxxmSJG4=
github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20210807121559-b41545a4f1e8/go.mod h1:k8CjDLBLxygTEj3D077OeH4SJsVE3mK60AyeO/C9sxs=
-github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20210820175050-dcc7a225178d h1:x9znF6oDcA2Q8L1Ud2TlNve//DRX4z380J3KMJ/xJ30=
github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20210820175050-dcc7a225178d/go.mod h1:wdgGPwXzih+QD2Q4nvMnGO0dm0D0rxmzQcSNLcW6fcg=
+github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220217153004-1622c70e5767/go.mod h1:yLgRpVlZ2heeeOpTgvEnG/yHL9q1keUu5ILQ6s2qpLU=
+github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220308060532-714cd5c18552 h1:5YpK44u/Ou4FTdzRvQy3iZiNE5W2E91j7OK/65V+Nv0=
+github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220308060532-714cd5c18552/go.mod h1:yLgRpVlZ2heeeOpTgvEnG/yHL9q1keUu5ILQ6s2qpLU=
github.com/hyperledger/aries-framework-go/spi v0.0.0-20210320144851-40976de98ccf/go.mod h1:fDr9wW00GJJl1lR1SFHmJW8utIocdvjO5RNhAYS05EY=
github.com/hyperledger/aries-framework-go/spi v0.0.0-20210322152545-e6ebe2c79a2a/go.mod h1:fDr9wW00GJJl1lR1SFHmJW8utIocdvjO5RNhAYS05EY=
github.com/hyperledger/aries-framework-go/spi v0.0.0-20210409151411-eeeb8508bd87/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
@@ -207,14 +211,21 @@ github.com/hyperledger/aries-framework-go/spi v0.0.0-20210603134946-53276bbf0c28
github.com/hyperledger/aries-framework-go/spi v0.0.0-20210603182844-353ecb34cf4d/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
github.com/hyperledger/aries-framework-go/spi v0.0.0-20210806210220-65863dbe349a/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
github.com/hyperledger/aries-framework-go/spi v0.0.0-20210807121559-b41545a4f1e8/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
-github.com/hyperledger/aries-framework-go/spi v0.0.0-20210820175050-dcc7a225178d h1:0JfPT4ORTdFMQknng3TiA2G/YY80+AMmty/47K7z4Rw=
+github.com/hyperledger/aries-framework-go/spi v0.0.0-20210818133831-4e22573c126d/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
+github.com/hyperledger/aries-framework-go/spi v0.0.0-20210820153043-8b6f36d10ab9/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
github.com/hyperledger/aries-framework-go/spi v0.0.0-20210820175050-dcc7a225178d/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
+github.com/hyperledger/aries-framework-go/spi v0.0.0-20211203210130-e927c9ed581a/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
+github.com/hyperledger/aries-framework-go/spi v0.0.0-20220217153004-1622c70e5767/go.mod h1:4bD5c5fj5K7rkQurVa/8I8+TfNcI4bxIBzaUNcxTOTg=
+github.com/hyperledger/aries-framework-go/spi v0.0.0-20220308060532-714cd5c18552 h1:Rtho/IS7GbQJAkPdTABC7udQBMk1AQveYTgxPubZ474=
+github.com/hyperledger/aries-framework-go/spi v0.0.0-20220308060532-714cd5c18552/go.mod h1:4bD5c5fj5K7rkQurVa/8I8+TfNcI4bxIBzaUNcxTOTg=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210324232048-34ff560ed041/go.mod h1:eKGEEe+PJNDQo7kVif3sUKBWwnsQDkE3gD/QlpmukcQ=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210409151411-eeeb8508bd87/go.mod h1:JHzDtgJLd0134iLFXLxGBjJF+Z+TgiElA/5oVgMazts=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210421203733-b5dfd703a8fc/go.mod h1:asiCVCtH/nocWKhZRMz12aFgdUh8lRHqKis0M8Ei/4I=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210603182844-353ecb34cf4d/go.mod h1:J0SlvlnETEdYojUW4om/UINH0Uobmbtw46cH4DGXv5g=
-github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210807121559-b41545a4f1e8 h1:9nd+4NsvBSjH3zIaM0B3Zr5kpaQHMmFFqzgVAE2fG7o=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210807121559-b41545a4f1e8/go.mod h1:3idbNcBl2wdRaETayzpY95KK5SfSzwXb5uqLW/Ldh0g=
+github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210820153043-8b6f36d10ab9/go.mod h1:7jEZdg455syX4f+ozLgwhYfIuiEQ/TgdIoOyALMwPG0=
+github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220217153004-1622c70e5767 h1:XyfULUaaWSj+JRaILaxTUHFh0CujzODJ5P4qJNjZM+w=
+github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220217153004-1622c70e5767/go.mod h1:HojN6OAh8ZtXBe5X2arcSOe1SLo5Dsjqto8ICjSLQ2g=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
diff --git a/pkg/client/issuecredential/rfc0593/event.go b/pkg/client/issuecredential/rfc0593/event.go
index d578ca4f0..f6c54789d 100644
--- a/pkg/client/issuecredential/rfc0593/event.go
+++ b/pkg/client/issuecredential/rfc0593/event.go
@@ -492,7 +492,7 @@ func signatureSuite(p Provider, proofType string) (signer.SignatureSuite, *Signa
return nil, nil, "", fmt.Errorf("failed to create a new signing key: %w", err)
}
- keyBytes, err := p.KMS().ExportPubKeyBytes(keyID)
+ keyBytes, _, err := p.KMS().ExportPubKeyBytes(keyID)
if err != nil {
return nil, nil, "", fmt.Errorf("failed to export signing key bytes: %w", err)
}
diff --git a/pkg/client/issuecredential/rfc0593/event_test.go b/pkg/client/issuecredential/rfc0593/event_test.go
index 7c2a66dfc..dac1fdcba 100644
--- a/pkg/client/issuecredential/rfc0593/event_test.go
+++ b/pkg/client/issuecredential/rfc0593/event_test.go
@@ -789,8 +789,9 @@ func newVCWithProof(t *testing.T, agent rfc0593.Provider, spec *rfc0593.Credenti
keyID, kh, err := agent.KMS().Create(kms.ED25519Type)
require.NoError(t, err)
- keyBytes, err := agent.KMS().ExportPubKeyBytes(keyID)
+ keyBytes, kt, err := agent.KMS().ExportPubKeyBytes(keyID)
require.NoError(t, err)
+ require.Equal(t, kms.ED25519Type, kt)
_, verificationMethod := fingerprint.CreateDIDKeyByCode(fingerprint.ED25519PubKeyMultiCodec, keyBytes)
diff --git a/pkg/controller/rest/rfc0593/operation_test.go b/pkg/controller/rest/rfc0593/operation_test.go
index 4264d99af..1bb452a6a 100644
--- a/pkg/controller/rest/rfc0593/operation_test.go
+++ b/pkg/controller/rest/rfc0593/operation_test.go
@@ -196,8 +196,9 @@ func signer(t *testing.T, ctx *context.Provider) (*suite.CryptoSigner, string) {
keyID, kh, err := ctx.KMS().Create(kms.ED25519Type)
require.NoError(t, err)
- keyBytes, err := ctx.KMS().ExportPubKeyBytes(keyID)
+ keyBytes, kt, err := ctx.KMS().ExportPubKeyBytes(keyID)
require.NoError(t, err)
+ require.Equal(t, kms.ED25519Type, kt)
s := suite.NewCryptoSigner(ctx.Crypto(), kh)
_, verMethod := fingerprint.CreateDIDKeyByCode(fingerprint.ED25519PubKeyMultiCodec, keyBytes)
diff --git a/pkg/crypto/tinkcrypto/primitive/composite/keyio/composite_key_export.go b/pkg/crypto/tinkcrypto/primitive/composite/keyio/composite_key_export.go
index 83da7288c..fe5515492 100644
--- a/pkg/crypto/tinkcrypto/primitive/composite/keyio/composite_key_export.go
+++ b/pkg/crypto/tinkcrypto/primitive/composite/keyio/composite_key_export.go
@@ -26,6 +26,7 @@ import (
"github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/aead"
"github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite/ecdh"
ecdhpb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/ecdh_aead_go_proto"
+ "github.com/hyperledger/aries-framework-go/pkg/kms"
)
// Package keyio supports exporting of Composite keys (aka Write) and converting the public key part of the a composite
@@ -38,6 +39,13 @@ const (
x25519ECDHKWPrivateKeyTypeURL = "type.hyperledger.org/hyperledger.aries.crypto.tink.X25519EcdhKwPrivateKey"
)
+//nolint:gochecknoglobals
+var ecdhKeyTypes = map[string]kms.KeyType{
+ "NIST_P256": kms.NISTP256ECDHKWType,
+ "NIST_P384": kms.NISTP384ECDHKWType,
+ "NIST_P521": kms.NISTP521ECDHKWType,
+}
+
// PubKeyWriter will write the raw bytes of a Tink KeySet's primary public key. The raw bytes are a marshaled
// composite.VerificationMethod type.
// The keyset must have a keyURL value equal to either one of the public key URLs:
@@ -47,7 +55,9 @@ const (
// Note: This writer should be used only for ECDH public key exports. Other export of public keys should be
// called via localkms package.
type PubKeyWriter struct {
- w io.Writer
+ // KeyType is Key Type of the written key. It's needed as Write() is an interface function and can't return it.
+ KeyType kms.KeyType
+ w io.Writer
}
// NewWriter creates a new PubKeyWriter instance.
@@ -59,7 +69,7 @@ func NewWriter(w io.Writer) *PubKeyWriter {
// Write writes the public keyset to the underlying w.Writer.
func (p *PubKeyWriter) Write(ks *tinkpb.Keyset) error {
- return write(p.w, ks)
+ return p.write(ks)
}
// WriteEncrypted writes the encrypted keyset to the underlying w.Writer.
@@ -67,7 +77,7 @@ func (p *PubKeyWriter) WriteEncrypted(_ *tinkpb.EncryptedKeyset) error {
return fmt.Errorf("write encrypted function not supported")
}
-func write(w io.Writer, msg *tinkpb.Keyset) error {
+func (p *PubKeyWriter) write(msg *tinkpb.Keyset) error {
ks := msg.Key
primaryKID := msg.PrimaryKeyId
created := false
@@ -76,7 +86,7 @@ func write(w io.Writer, msg *tinkpb.Keyset) error {
for _, key := range ks {
if key.KeyId == primaryKID && key.Status == tinkpb.KeyStatusType_ENABLED {
- created, err = writePubKey(w, key)
+ created, err = p.writePubKey(key)
if err != nil {
return err
}
@@ -92,8 +102,8 @@ func write(w io.Writer, msg *tinkpb.Keyset) error {
return nil
}
-func writePubKey(w io.Writer, key *tinkpb.Keyset_Key) (bool, error) {
- pubKey, err := protoToCompositeKey(key.KeyData)
+func (p *PubKeyWriter) writePubKey(key *tinkpb.Keyset_Key) (bool, error) {
+ pubKey, kt, err := protoToCompositeKey(key.KeyData)
if err != nil {
return false, err
}
@@ -103,15 +113,17 @@ func writePubKey(w io.Writer, key *tinkpb.Keyset_Key) (bool, error) {
return false, err
}
- n, err := w.Write(mPubKey)
+ n, err := p.w.Write(mPubKey)
if err != nil {
return false, err
}
+ p.KeyType = kt
+
return n > 0, nil
}
-func protoToCompositeKey(keyData *tinkpb.KeyData) (*cryptoapi.PublicKey, error) {
+func protoToCompositeKey(keyData *tinkpb.KeyData) (*cryptoapi.PublicKey, kms.KeyType, error) {
var (
cKey compositeKeyGetter
err error
@@ -121,40 +133,45 @@ func protoToCompositeKey(keyData *tinkpb.KeyData) (*cryptoapi.PublicKey, error)
case nistPECDHKWPublicKeyTypeURL, x25519ECDHKWPublicKeyTypeURL:
cKey, err = newECDHKey(keyData.Value)
if err != nil {
- return nil, err
+ return nil, "", err
}
default:
- return nil, fmt.Errorf("can't export key with keyURL:%s", keyData.TypeUrl)
+ return nil, "", fmt.Errorf("can't export key with keyURL:%s", keyData.TypeUrl)
}
return buildKey(cKey)
}
-func buildKey(c compositeKeyGetter) (*cryptoapi.PublicKey, error) {
+func buildKey(c compositeKeyGetter) (*cryptoapi.PublicKey, kms.KeyType, error) {
curveName := c.curveName()
keyTypeName := c.keyType()
return buildCompositeKey(c.kid(), keyTypeName, curveName, c.x(), c.y())
}
-func buildCompositeKey(kid, keyType, curve string, x, y []byte) (*cryptoapi.PublicKey, error) {
+func buildCompositeKey(kid, keyType, curve string, x, y []byte) (*cryptoapi.PublicKey, kms.KeyType, error) {
+ var kt kms.KeyType
+
// validate keyType and curve
switch keyType {
case ecdhpb.KeyType_EC.String():
// validate NIST P curves
_, err := hybrid.GetCurve(curve)
if err != nil {
- return nil, fmt.Errorf("undefined EC curve: %w", err)
+ return nil, "", fmt.Errorf("undefined EC curve: %w", err)
}
+
+ kt = ecdhKeyTypes[curve]
case ecdhpb.KeyType_OKP.String():
if curve != commonpb.EllipticCurveType_CURVE25519.String() {
- return nil, fmt.Errorf("invalid OKP curve: %s", curve)
+ return nil, "", fmt.Errorf("invalid OKP curve: %s", curve)
}
// use JWK curve name when exporting the key.
curve = "X25519"
+ kt = kms.X25519ECDHKWType
default:
- return nil, fmt.Errorf("invalid keyType: %s", keyType)
+ return nil, "", fmt.Errorf("invalid keyType: %s", keyType)
}
return &cryptoapi.PublicKey{
@@ -163,7 +180,7 @@ func buildCompositeKey(kid, keyType, curve string, x, y []byte) (*cryptoapi.Publ
Curve: curve,
X: x,
Y: y,
- }, nil
+ }, kt, nil
}
type compositeKeyGetter interface {
diff --git a/pkg/crypto/tinkcrypto/primitive/composite/keyio/composite_key_export_import_test.go b/pkg/crypto/tinkcrypto/primitive/composite/keyio/composite_key_export_import_test.go
index 509a33016..6c08fce4a 100644
--- a/pkg/crypto/tinkcrypto/primitive/composite/keyio/composite_key_export_import_test.go
+++ b/pkg/crypto/tinkcrypto/primitive/composite/keyio/composite_key_export_import_test.go
@@ -206,12 +206,12 @@ func TestNegativeCases(t *testing.T) {
})
t.Run("test buildCompositeKey() with bad EC curve", func(t *testing.T) {
- _, err := buildCompositeKey("", ecdhpb.KeyType_EC.String(), "BAD", nil, nil)
+ _, _, err := buildCompositeKey("", ecdhpb.KeyType_EC.String(), "BAD", nil, nil)
require.EqualError(t, err, "undefined EC curve: unsupported curve")
})
t.Run("test buildCompositeKey() with bad OKP curve", func(t *testing.T) {
- _, err := buildCompositeKey("", ecdhpb.KeyType_OKP.String(), "BAD", nil, nil)
+ _, _, err := buildCompositeKey("", ecdhpb.KeyType_OKP.String(), "BAD", nil, nil)
require.EqualError(t, err, "invalid OKP curve: BAD")
})
@@ -232,7 +232,7 @@ func TestNegativeCases(t *testing.T) {
})
require.NoError(t, err)
- _, err = protoToCompositeKey(&tinkpb.KeyData{
+ _, _, err = protoToCompositeKey(&tinkpb.KeyData{
TypeUrl: nistPECDHKWPublicKeyTypeURL,
Value: mKey,
KeyMaterialType: 0,
@@ -260,7 +260,8 @@ func TestNegativeCases(t *testing.T) {
t.Run("test write() should fail with empty key set", func(t *testing.T) {
buf := new(bytes.Buffer)
- err := write(buf, &tinkpb.Keyset{})
+ pw := &PubKeyWriter{w: buf}
+ err := pw.write(&tinkpb.Keyset{})
require.Error(t, err)
})
@@ -281,7 +282,8 @@ func TestNegativeCases(t *testing.T) {
})
require.NoError(t, err)
- err = write(&failWriter{}, &tinkpb.Keyset{
+ pw := &PubKeyWriter{w: &failWriter{}}
+ err = pw.write(&tinkpb.Keyset{
PrimaryKeyId: 0,
Key: []*tinkpb.Keyset_Key{
{
diff --git a/pkg/didcomm/protocol/decorator/decorator_test.go b/pkg/didcomm/protocol/decorator/decorator_test.go
index 8c36220bc..78805eb14 100644
--- a/pkg/didcomm/protocol/decorator/decorator_test.go
+++ b/pkg/didcomm/protocol/decorator/decorator_test.go
@@ -225,8 +225,9 @@ func TestSignVerify(t *testing.T) {
kid2, kh2, err2 := k.ImportPrivateKey(priv, testCase.keyType)
require.NoError(t, err2)
- pub, err2 := k.ExportPubKeyBytes(kid2)
+ pub, kt, err2 := k.ExportPubKeyBytes(kid2)
require.NoError(t, err2)
+ require.Equal(t, testCase.keyType, kt)
data := mockAttachmentData()
diff --git a/pkg/didcomm/protocol/didexchange/service_test.go b/pkg/didcomm/protocol/didexchange/service_test.go
index f7d4b6312..57aad6b0c 100644
--- a/pkg/didcomm/protocol/didexchange/service_test.go
+++ b/pkg/didcomm/protocol/didexchange/service_test.go
@@ -2365,8 +2365,9 @@ func signedDocAttach(t *testing.T, doc *did.Doc) *decorator.Attachment {
kid, kh, err := kmsInstance.Create(kms.ED25519Type)
require.NoError(t, err)
- pub, err := kmsInstance.ExportPubKeyBytes(kid)
+ pub, kt, err := kmsInstance.ExportPubKeyBytes(kid)
require.NoError(t, err)
+ require.Equal(t, kms.ED25519Type, kt)
c := &tinkcrypto.Crypto{}
diff --git a/pkg/doc/presexch/api_test.go b/pkg/doc/presexch/api_test.go
index 95f1fdd3e..ec969aa74 100644
--- a/pkg/doc/presexch/api_test.go
+++ b/pkg/doc/presexch/api_test.go
@@ -406,8 +406,9 @@ func newSignedVC(t *testing.T,
signer := suite.NewCryptoSigner(agent.Crypto(), kh)
now := time.Now()
- pubKey, err := agent.KMS().ExportPubKeyBytes(keyID)
+ pubKey, kt, err := agent.KMS().ExportPubKeyBytes(keyID)
require.NoError(t, err)
+ require.Equal(t, kms.ED25519Type, kt)
_, verMethod := fingerprint.CreateDIDKeyByCode(fingerprint.ED25519PubKeyMultiCodec, pubKey)
diff --git a/pkg/doc/signature/suite/ed25519signature2018/suite_crypto_test.go b/pkg/doc/signature/suite/ed25519signature2018/suite_crypto_test.go
index 6842587e2..71b992b70 100644
--- a/pkg/doc/signature/suite/ed25519signature2018/suite_crypto_test.go
+++ b/pkg/doc/signature/suite/ed25519signature2018/suite_crypto_test.go
@@ -47,7 +47,7 @@ func TestNewCryptoSignerAndVerifier(t *testing.T) {
panic("failed to create a signature")
}
- pubKeyBytes, err := lKMS.ExportPubKeyBytes(kid)
+ pubKeyBytes, _, err := lKMS.ExportPubKeyBytes(kid)
if err != nil {
panic("failed to export public key bytes")
}
diff --git a/pkg/doc/signature/suite/jsonwebsignature2020/suite_crypto_test.go b/pkg/doc/signature/suite/jsonwebsignature2020/suite_crypto_test.go
index efa171c6c..779403e42 100644
--- a/pkg/doc/signature/suite/jsonwebsignature2020/suite_crypto_test.go
+++ b/pkg/doc/signature/suite/jsonwebsignature2020/suite_crypto_test.go
@@ -45,7 +45,7 @@ func TestNewCryptoSignerAndVerifier(t *testing.T) {
docSig, err := ss.Sign(doc)
require.NoError(t, err)
- pubKeyBytes, err := lKMS.ExportPubKeyBytes(kid)
+ pubKeyBytes, _, err := lKMS.ExportPubKeyBytes(kid)
require.NoError(t, err)
pubKey := &sigverifier.PublicKey{
diff --git a/pkg/doc/util/signature/internal/signer/crypto_signer.go b/pkg/doc/util/signature/internal/signer/crypto_signer.go
index da877ee96..12a9f01cd 100644
--- a/pkg/doc/util/signature/internal/signer/crypto_signer.go
+++ b/pkg/doc/util/signature/internal/signer/crypto_signer.go
@@ -55,7 +55,7 @@ func NewCryptoSigner(crypto cryptoapi.Crypto, kms kmsapi.KeyManager, keyType kms
return nil, err
}
- pubKeyBytes, err := kms.ExportPubKeyBytes(kid)
+ pubKeyBytes, _, err := kms.ExportPubKeyBytes(kid)
if err != nil {
return nil, err
}
diff --git a/pkg/internal/gomocks/kms/mocks.gen.go b/pkg/internal/gomocks/kms/mocks.gen.go
index 6a509e7d9..b50696275 100644
--- a/pkg/internal/gomocks/kms/mocks.gen.go
+++ b/pkg/internal/gomocks/kms/mocks.gen.go
@@ -120,12 +120,13 @@ func (mr *MockKeyManagerMockRecorder) CreateAndExportPubKeyBytes(arg0 interface{
}
// ExportPubKeyBytes mocks base method.
-func (m *MockKeyManager) ExportPubKeyBytes(arg0 string) ([]byte, error) {
+func (m *MockKeyManager) ExportPubKeyBytes(arg0 string) ([]byte, kms.KeyType, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ExportPubKeyBytes", arg0)
ret0, _ := ret[0].([]byte)
- ret1, _ := ret[1].(error)
- return ret0, ret1
+ ret1, _ := ret[1].(kms.KeyType)
+ ret2, _ := ret[2].(error)
+ return ret0, ret1, ret2
}
// ExportPubKeyBytes indicates an expected call of ExportPubKeyBytes.
diff --git a/pkg/kms/api.go b/pkg/kms/api.go
index 123534081..feea7ee30 100644
--- a/pkg/kms/api.go
+++ b/pkg/kms/api.go
@@ -41,7 +41,7 @@ type KeyManager interface {
// Returns:
// - marshalled public key []byte
// - error if it fails to export the public key bytes
- ExportPubKeyBytes(keyID string) ([]byte, error)
+ ExportPubKeyBytes(keyID string) ([]byte, KeyType, error)
// CreateAndExportPubKeyBytes will create a key of type kt and export its public key in raw bytes and returns it.
// The key must be an asymmetric key.
// Returns:
diff --git a/pkg/kms/localkms/localkms.go b/pkg/kms/localkms/localkms.go
index eb70fd40d..bc2b1025b 100644
--- a/pkg/kms/localkms/localkms.go
+++ b/pkg/kms/localkms/localkms.go
@@ -313,18 +313,20 @@ func (l *LocalKMS) getKeySet(id string) (*keyset.Handle, error) {
// Returns:
// - marshalled public key []byte
// - error if it fails to export the public key bytes
-func (l *LocalKMS) ExportPubKeyBytes(id string) ([]byte, error) {
+func (l *LocalKMS) ExportPubKeyBytes(id string) ([]byte, kms.KeyType, error) {
kh, err := l.getKeySet(id)
if err != nil {
- return nil, fmt.Errorf("exportPubKeyBytes: failed to get keyset handle: %w", err)
+ return nil, "", fmt.Errorf("exportPubKeyBytes: failed to get keyset handle: %w", err)
}
- marshalledKey, err := l.exportPubKeyBytes(kh)
+ marshalledKey, kt, err := l.exportPubKeyBytes(kh)
if err != nil {
- return nil, fmt.Errorf("exportPubKeyBytes: failed to export marshalled key: %w", err)
+ return nil, "", fmt.Errorf("exportPubKeyBytes: failed to export marshalled key: %w", err)
}
- return setKIDForCompositeKey(marshalledKey, id)
+ mUpdatedKey, err := setKIDForCompositeKey(marshalledKey, id)
+
+ return mUpdatedKey, kt, err
}
func setKIDForCompositeKey(marshalledKey []byte, kid string) ([]byte, error) {
@@ -340,11 +342,11 @@ func setKIDForCompositeKey(marshalledKey []byte, kid string) ([]byte, error) {
return json.Marshal(pubKey)
}
-func (l *LocalKMS) exportPubKeyBytes(kh *keyset.Handle) ([]byte, error) {
+func (l *LocalKMS) exportPubKeyBytes(kh *keyset.Handle) ([]byte, kms.KeyType, error) {
// kh must be a private asymmetric key in order to extract its public key
pubKH, err := kh.Public()
if err != nil {
- return nil, fmt.Errorf("exportPubKeyBytes: failed to get public keyset handle: %w", err)
+ return nil, "", fmt.Errorf("exportPubKeyBytes: failed to get public keyset handle: %w", err)
}
buf := new(bytes.Buffer)
@@ -352,11 +354,11 @@ func (l *LocalKMS) exportPubKeyBytes(kh *keyset.Handle) ([]byte, error) {
err = pubKH.WriteWithNoSecrets(pubKeyWriter)
if err != nil {
- return nil, fmt.Errorf("exportPubKeyBytes: failed to create keyset with no secrets (public "+
+ return nil, "", fmt.Errorf("exportPubKeyBytes: failed to create keyset with no secrets (public "+
"key material): %w", err)
}
- return buf.Bytes(), nil
+ return buf.Bytes(), pubKeyWriter.KeyType, nil
}
// CreateAndExportPubKeyBytes will create a key of type kt and export its public key in raw bytes and returns it.
@@ -371,7 +373,7 @@ func (l *LocalKMS) CreateAndExportPubKeyBytes(kt kms.KeyType) (string, []byte, e
return "", nil, fmt.Errorf("createAndExportPubKeyBytes: failed to create new key: %w", err)
}
- pubKeyBytes, err := l.ExportPubKeyBytes(kid)
+ pubKeyBytes, _, err := l.ExportPubKeyBytes(kid)
if err != nil {
return "", nil, fmt.Errorf("createAndExportPubKeyBytes: failed to export new public key bytes: %w", err)
}
@@ -412,7 +414,7 @@ func (l *LocalKMS) ImportPrivateKey(privKey interface{}, kt kms.KeyType,
}
func (l *LocalKMS) generateKID(kh *keyset.Handle, kt kms.KeyType) (string, error) {
- keyBytes, err := l.exportPubKeyBytes(kh)
+ keyBytes, _, err := l.exportPubKeyBytes(kh)
if err != nil {
return "", fmt.Errorf("generateKID: failed to export public key: %w", err)
}
diff --git a/pkg/kms/localkms/localkms_test.go b/pkg/kms/localkms/localkms_test.go
index 3d9d6b528..f531ea296 100644
--- a/pkg/kms/localkms/localkms_test.go
+++ b/pkg/kms/localkms/localkms_test.go
@@ -205,7 +205,7 @@ func TestCreateGetRotateKey_Failure(t *testing.T) {
kid, _, err := kmsStorage.Create(kms.AES128GCM)
require.NoError(t, err)
- _, err = kmsStorage.ExportPubKeyBytes(kid)
+ _, _, err = kmsStorage.ExportPubKeyBytes(kid)
require.EqualError(t, err, "exportPubKeyBytes: failed to export marshalled key: exportPubKeyBytes: "+
"failed to get public keyset handle: keyset.Handle: keyset.Handle: keyset contains a non-private key")
})
@@ -367,13 +367,15 @@ func TestLocalKMS_Success(t *testing.T) {
require.Equal(t, len(readKHPrimitives.Entries), len(rotatedKHPrimitives.Entries))
if strings.Contains(string(v), "ECDSA") || v == kms.ED25519Type || v == kms.BLS12381G2Type {
- pubKeyBytes, e := kmsService.ExportPubKeyBytes(keyID)
+ pubKeyBytes, kt, e := kmsService.ExportPubKeyBytes(keyID)
require.Errorf(t, e, "KeyID has been rotated. An error must be returned")
require.Empty(t, pubKeyBytes)
+ require.Empty(t, kt)
- pubKeyBytes, e = kmsService.ExportPubKeyBytes(newKeyID)
+ pubKeyBytes, kt, e = kmsService.ExportPubKeyBytes(newKeyID)
require.NoError(t, e)
require.NotEmpty(t, pubKeyBytes)
+ require.Equal(t, v, kt)
kh, e := kmsService.PubKeyBytesToHandle(pubKeyBytes, v)
require.NoError(t, e)
@@ -501,9 +503,10 @@ func TestLocalKMS_ImportPrivateKey(t *testing.T) { // nolint:gocyclo
ksID, _, err := kmsService.ImportPrivateKey(privKey, tt.keyType)
require.NoError(t, err)
- pubKeyBytes, err := kmsService.ExportPubKeyBytes(ksID)
+ pubKeyBytes, kt, err := kmsService.ExportPubKeyBytes(ksID)
require.NoError(t, err)
require.EqualValues(t, pubKey, pubKeyBytes)
+ require.Equal(t, tt.keyType, kt)
return
}
@@ -519,8 +522,9 @@ func TestLocalKMS_ImportPrivateKey(t *testing.T) { // nolint:gocyclo
ksID, _, err := kmsService.ImportPrivateKey(privKey, tt.keyType)
require.NoError(t, err)
- pubKeyBytes, err := kmsService.ExportPubKeyBytes(ksID)
+ pubKeyBytes, kt, err := kmsService.ExportPubKeyBytes(ksID)
require.NoError(t, err)
+ require.Equal(t, tt.keyType, kt)
expectedPubKeyBytes, err := pubKey.Marshal()
require.NoError(t, err)
@@ -549,8 +553,9 @@ func TestLocalKMS_ImportPrivateKey(t *testing.T) { // nolint:gocyclo
}
// export marshaled public key to verify it against the original public key (marshalled)
- actualPubKey, err := kmsService.ExportPubKeyBytes(ksID)
+ actualPubKey, kt, err := kmsService.ExportPubKeyBytes(ksID)
require.NoError(t, err)
+ require.Equal(t, tt.keyType, kt)
var expectedPubKey []byte
diff --git a/pkg/kms/localkms/pubkey_writer.go b/pkg/kms/localkms/pubkey_writer.go
index 136512ff2..54b2dc7ba 100644
--- a/pkg/kms/localkms/pubkey_writer.go
+++ b/pkg/kms/localkms/pubkey_writer.go
@@ -23,6 +23,7 @@ import (
"github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite/keyio"
bbspb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/bbs_go_proto"
+ "github.com/hyperledger/aries-framework-go/pkg/kms"
)
const (
@@ -31,14 +32,28 @@ const (
nistPECDHKWPublicKeyTypeURL = "type.hyperledger.org/hyperledger.aries.crypto.tink.NistPEcdhKwPublicKey"
x25519ECDHKWPublicKeyTypeURL = "type.hyperledger.org/hyperledger.aries.crypto.tink.X25519EcdhKwPublicKey"
bbsVerifierKeyTypeURL = "type.hyperledger.org/hyperledger.aries.crypto.tink.BBSPublicKey"
+ derPrefix = "der-"
+ p13163Prefix = "p1363-"
)
+//nolint:gochecknoglobals
+var ecdsaKMSKeyTypes = map[string]kms.KeyType{
+ derPrefix + "NIST_P256": kms.ECDSAP256TypeDER,
+ derPrefix + "NIST_P384": kms.ECDSAP384TypeDER,
+ derPrefix + "NIST_P521": kms.ECDSAP521TypeDER,
+ p13163Prefix + "NIST_P256": kms.ECDSAP256TypeIEEEP1363,
+ p13163Prefix + "NIST_P384": kms.ECDSAP384TypeIEEEP1363,
+ p13163Prefix + "NIST_P521": kms.ECDSAP521TypeIEEEP1363,
+}
+
// PubKeyWriter will write the raw bytes of a Tink KeySet's primary public key
// The keyset must be one of the keyURLs defined above
// Note: Only signing public keys and ecdh key types created in tinkcrypto can be exported through this PubKeyWriter.
// ECHDES has its own Writer to export its public keys due to cyclic dependency.
type PubKeyWriter struct {
- w io.Writer
+ // KeyType is Key Type of the written key. It's needed as Write() is an interface function and can't return it.
+ KeyType kms.KeyType
+ w io.Writer
}
// NewWriter creates a new PubKeyWriter instance.
@@ -50,7 +65,14 @@ func NewWriter(w io.Writer) *PubKeyWriter {
// Write writes the public keyset to the underlying w.Writer.
func (p *PubKeyWriter) Write(keyset *tinkpb.Keyset) error {
- return write(p.w, keyset)
+ keyType, err := write(p.w, keyset)
+ if err != nil {
+ return err
+ }
+
+ p.KeyType = keyType
+
+ return nil
}
// WriteEncrypted writes the encrypted keyset to the underlying w.Writer.
@@ -58,32 +80,36 @@ func (p *PubKeyWriter) WriteEncrypted(keyset *tinkpb.EncryptedKeyset) error {
return fmt.Errorf("write encrypted function not supported")
}
-func write(w io.Writer, msg *tinkpb.Keyset) error {
+func write(w io.Writer, msg *tinkpb.Keyset) (kms.KeyType, error) {
ks := msg.Key
primaryKID := msg.PrimaryKeyId
created := false
- var err error
+ var (
+ kt kms.KeyType
+ err error
+ )
for _, key := range ks {
if key.KeyId == primaryKID && key.Status == tinkpb.KeyStatusType_ENABLED {
switch key.KeyData.TypeUrl {
case ecdsaVerifierTypeURL, ed25519VerifierTypeURL, bbsVerifierKeyTypeURL:
- created, err = writePubKey(w, key)
+ created, kt, err = writePubKey(w, key)
if err != nil {
- return err
+ return "", err
}
case nistPECDHKWPublicKeyTypeURL, x25519ECDHKWPublicKeyTypeURL:
pkW := keyio.NewWriter(w)
err = pkW.Write(msg)
if err != nil {
- return err
+ return "", err
}
+ kt = pkW.KeyType
created = true
default:
- return fmt.Errorf("key type not supported for writing raw key bytes: %s", key.KeyData.TypeUrl)
+ return "", fmt.Errorf("key type not supported for writing raw key bytes: %s", key.KeyData.TypeUrl)
}
break
@@ -91,14 +117,17 @@ func write(w io.Writer, msg *tinkpb.Keyset) error {
}
if !created {
- return fmt.Errorf("key not written")
+ return "", fmt.Errorf("key not written")
}
- return nil
+ return kt, nil
}
-func writePubKey(w io.Writer, key *tinkpb.Keyset_Key) (bool, error) {
- var marshaledRawPubKey []byte
+func writePubKey(w io.Writer, key *tinkpb.Keyset_Key) (bool, kms.KeyType, error) {
+ var (
+ marshaledRawPubKey []byte
+ kt kms.KeyType
+ )
// TODO add other key types than the ones below and other than nistPECDHKWPublicKeyTypeURL and
// TODO x25519ECDHKWPublicKeyTypeURL(eg: secp256k1 when introduced in KMS).
@@ -108,56 +137,61 @@ func writePubKey(w io.Writer, key *tinkpb.Keyset_Key) (bool, error) {
err := proto.Unmarshal(key.KeyData.Value, pubKeyProto)
if err != nil {
- return false, err
+ return false, "", err
}
- marshaledRawPubKey, err = getMarshalledECDSAKeyValueFromProto(pubKeyProto)
+ marshaledRawPubKey, kt, err = getMarshalledECDSAKeyValueFromProto(pubKeyProto)
if err != nil {
- return false, err
+ return false, "", err
}
case ed25519VerifierTypeURL:
pubKeyProto := new(ed25519pb.Ed25519PublicKey)
err := proto.Unmarshal(key.KeyData.Value, pubKeyProto)
if err != nil {
- return false, err
+ return false, "", err
}
marshaledRawPubKey = make([]byte, len(pubKeyProto.KeyValue))
copy(marshaledRawPubKey, pubKeyProto.KeyValue)
+
+ kt = kms.ED25519Type
case bbsVerifierKeyTypeURL:
pubKeyProto := new(bbspb.BBSPublicKey)
err := proto.Unmarshal(key.KeyData.Value, pubKeyProto)
if err != nil {
- return false, err
+ return false, "", err
}
marshaledRawPubKey = make([]byte, len(pubKeyProto.KeyValue))
copy(marshaledRawPubKey, pubKeyProto.KeyValue)
+
+ kt = kms.BLS12381G2Type
default:
- return false, fmt.Errorf("can't export key with keyURL:%s", key.KeyData.TypeUrl)
+ return false, "", fmt.Errorf("can't export key with keyURL:%s", key.KeyData.TypeUrl)
}
n, err := w.Write(marshaledRawPubKey)
if err != nil {
- return false, nil //nolint:nilerr
+ return false, "", nil //nolint:nilerr
}
- return n > 0, nil
+ return n > 0, kt, nil
}
-func getMarshalledECDSAKeyValueFromProto(pubKeyProto *ecdsapb.EcdsaPublicKey) ([]byte, error) {
+func getMarshalledECDSAKeyValueFromProto(pubKeyProto *ecdsapb.EcdsaPublicKey) ([]byte, kms.KeyType, error) {
var (
marshaledRawPubKey []byte
err error
+ kt kms.KeyType
)
curveName := commonpb.EllipticCurveType_name[int32(pubKeyProto.Params.Curve)]
curve := subtle.GetCurve(curveName)
if curve == nil {
- return nil, fmt.Errorf("undefined curve")
+ return nil, "", fmt.Errorf("undefined curve")
}
pubKey := ecdsa.PublicKey{
@@ -173,13 +207,16 @@ func getMarshalledECDSAKeyValueFromProto(pubKeyProto *ecdsapb.EcdsaPublicKey) ([
case ecdsapb.EcdsaSignatureEncoding_DER:
marshaledRawPubKey, err = x509.MarshalPKIXPublicKey(&pubKey)
if err != nil {
- return nil, err
+ return nil, "", err
}
+
+ kt = ecdsaKMSKeyTypes[derPrefix+curveName]
case ecdsapb.EcdsaSignatureEncoding_IEEE_P1363:
marshaledRawPubKey = elliptic.Marshal(curve, pubKey.X, pubKey.Y)
+ kt = ecdsaKMSKeyTypes[p13163Prefix+curveName]
default:
- return nil, fmt.Errorf("can't export key with bad key encoding: '%s'", pubKeyProto.Params.Encoding)
+ return nil, "", fmt.Errorf("can't export key with bad key encoding: '%s'", pubKeyProto.Params.Encoding)
}
- return marshaledRawPubKey, nil
+ return marshaledRawPubKey, kt, nil
}
diff --git a/pkg/kms/webkms/remotekms.go b/pkg/kms/webkms/remotekms.go
index e86fb019b..b93fa8f64 100644
--- a/pkg/kms/webkms/remotekms.go
+++ b/pkg/kms/webkms/remotekms.go
@@ -68,6 +68,7 @@ type createKeyResp struct {
type exportKeyResp struct {
PublicKey []byte `json:"public_key"`
+ KeyType string `json:"key_type"`
}
type importKeyReq struct {
@@ -331,7 +332,7 @@ func (r *RemoteKMS) Rotate(kt kms.KeyType, keyID string) (string, interface{}, e
// Returns:
// - marshalled public key []byte
// - error if it fails to export the public key bytes
-func (r *RemoteKMS) ExportPubKeyBytes(keyID string) ([]byte, error) {
+func (r *RemoteKMS) ExportPubKeyBytes(keyID string) ([]byte, kms.KeyType, error) {
startExport := time.Now()
keyURL := r.buildKIDURL(keyID)
@@ -339,7 +340,7 @@ func (r *RemoteKMS) ExportPubKeyBytes(keyID string) ([]byte, error) {
resp, err := r.getHTTPRequest(destination)
if err != nil {
- return nil, fmt.Errorf("posting GET ExportPubKeyBytes key failed [%s, %w]", destination, err)
+ return nil, "", fmt.Errorf("posting GET ExportPubKeyBytes key failed [%s, %w]", destination, err)
}
// handle response
@@ -349,12 +350,12 @@ func (r *RemoteKMS) ExportPubKeyBytes(keyID string) ([]byte, error) {
err = readResponse(resp, &httpResp, r.unmarshalFunc)
if err != nil {
- return nil, fmt.Errorf("export pub key bytes failed [%s, %w]", destination, err)
+ return nil, "", fmt.Errorf("export pub key bytes failed [%s, %w]", destination, err)
}
logger.Debugf("overall ExportPubKeyBytes duration: %s", time.Since(startExport))
- return httpResp.PublicKey, nil
+ return httpResp.PublicKey, kms.KeyType(httpResp.KeyType), nil
}
// CreateAndExportPubKeyBytes will remotely create a key of type kt and export its public key in raw bytes and returns
diff --git a/pkg/kms/webkms/remotekms_test.go b/pkg/kms/webkms/remotekms_test.go
index 0c891884a..816475442 100644
--- a/pkg/kms/webkms/remotekms_test.go
+++ b/pkg/kms/webkms/remotekms_test.go
@@ -52,7 +52,7 @@ func TestRemoteKeyStore(t *testing.T) {
marshalledPubKey := elliptic.Marshal(pvKey.PublicKey.Curve, pvKey.PublicKey.X, pvKey.PublicKey.Y)
hf := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- err = processPOSTRequest(w, r, defaultKeyStoreID, defaultKID, marshalledPubKey)
+ err = processPOSTRequest(w, r, defaultKeyStoreID, defaultKID, marshalledPubKey, kms.ECDSAP256TypeIEEEP1363)
w.WriteHeader(http.StatusCreated)
require.NoError(t, err)
})
@@ -155,7 +155,7 @@ func TestRemoteKeyStore(t *testing.T) {
t.Run("New, Create, Get, Export/Import success, all other functions should fail", func(t *testing.T) {
remoteKMS := New(defaultKeystoreURL, client)
- kid, keyURL, err := remoteKMS.Create(kms.ED25519Type)
+ kid, keyURL, err := remoteKMS.Create(kms.ECDSAP256TypeIEEEP1363)
require.NoError(t, err)
require.Equal(t, defaultKID, kid)
require.Contains(t, keyURL, fmt.Sprintf("%s/keys/%s", defaultKeystoreURL, defaultKID))
@@ -173,9 +173,10 @@ func TestRemoteKeyStore(t *testing.T) {
require.NoError(t, err)
require.EqualValues(t, keyURL, kh)
- pubKey, err := remoteKMS.ExportPubKeyBytes(kid)
+ pubKey, kt, err := remoteKMS.ExportPubKeyBytes(kid)
require.NoError(t, err)
require.EqualValues(t, marshalledPubKey, pubKey)
+ require.Equal(t, kms.ECDSAP256TypeIEEEP1363, kt)
t.Run("ExportPubKeyBytes API error", func(t *testing.T) {
_hf := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
@@ -190,7 +191,7 @@ func TestRemoteKeyStore(t *testing.T) {
tmpKMS := New(_url, _client)
- _, err = tmpKMS.ExportPubKeyBytes("kid")
+ _, _, err = tmpKMS.ExportPubKeyBytes("kid")
require.Contains(t, err.Error(), "api error msg")
})
@@ -204,7 +205,7 @@ func TestRemoteKeyStore(t *testing.T) {
// switch the marshaller in remoteKMS3 to force an error in ExportPubKeyBytes
remoteKMS3.unmarshalFunc = failingUnmarshal
- _, err = remoteKMS3.ExportPubKeyBytes(kid1)
+ _, _, err = remoteKMS3.ExportPubKeyBytes(kid1)
require.Contains(t, err.Error(), "unmarshal failed")
require.Contains(t, err.Error(), "failingUnmarshal always fails")
@@ -214,7 +215,7 @@ func TestRemoteKeyStore(t *testing.T) {
// test GET http function failure
remoteKMS3.keystoreURL = "``#$%"
- _, err = remoteKMS3.ExportPubKeyBytes(kid1)
+ _, _, err = remoteKMS3.ExportPubKeyBytes(kid1)
require.Contains(t, err.Error(), "posting GET ExportPubKeyBytes key failed")
require.Contains(t, err.Error(), "build get request error")
})
@@ -227,7 +228,7 @@ func TestRemoteKeyStore(t *testing.T) {
blankClient := &http.Client{}
remoteKMS2 := New(defaultKeystoreURL, blankClient)
- _, err = remoteKMS2.ExportPubKeyBytes(kid)
+ _, _, err = remoteKMS2.ExportPubKeyBytes(kid)
require.Contains(t, err.Error(), "posting GET ExportPubKeyBytes key failed")
})
@@ -284,7 +285,7 @@ func TestRemoteKeyStoreWithHeadersFunc(t *testing.T) {
marshalledPubKey := elliptic.Marshal(pvKey.PublicKey.Curve, pvKey.PublicKey.X, pvKey.PublicKey.Y)
hf := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- err = processPOSTRequest(w, r, defaultKeyStoreID, defaultKID, marshalledPubKey)
+ err = processPOSTRequest(w, r, defaultKeyStoreID, defaultKID, marshalledPubKey, kms.ECDSAP256TypeIEEEP1363)
w.WriteHeader(http.StatusCreated)
require.NoError(t, err)
})
@@ -401,7 +402,7 @@ func TestCloseResponseBody(t *testing.T) {
}
func processPOSTRequest(w http.ResponseWriter, r *http.Request, keysetID, kid string,
- defaultExportPubKey []byte) error {
+ defaultExportPubKey []byte, defaultExportKeyType kms.KeyType) error {
xRootCapabilityHeaderValue := []byte("DUMMY")
if valid := validateHTTPMethod(w, r); !valid {
@@ -417,7 +418,7 @@ func processPOSTRequest(w http.ResponseWriter, r *http.Request, keysetID, kid st
}
if strings.LastIndex(r.URL.Path, "/export") == len(r.URL.Path)-len("/export") {
- return processExportKeyRequest(w, defaultExportPubKey)
+ return processExportKeyRequest(w, defaultExportPubKey, defaultExportKeyType)
}
resp := &createKeyStoreResp{
@@ -463,9 +464,10 @@ func processCreateKeyRequest(w http.ResponseWriter, r *http.Request, keysetID, k
return nil
}
-func processExportKeyRequest(w io.Writer, defaultExportPubKey []byte) error {
+func processExportKeyRequest(w io.Writer, defaultExportPubKey []byte, defaultExportKeyType kms.KeyType) error {
resp := &exportKeyResp{
PublicKey: defaultExportPubKey,
+ KeyType: string(defaultExportKeyType),
}
mResp, err := json.Marshal(resp)
diff --git a/pkg/mock/kms/mock_kms.go b/pkg/mock/kms/mock_kms.go
index c0365bcee..4dc6ff389 100644
--- a/pkg/mock/kms/mock_kms.go
+++ b/pkg/mock/kms/mock_kms.go
@@ -33,6 +33,7 @@ type KeyManager struct {
RotateKeyErr error
ExportPubKeyBytesErr error
ExportPubKeyBytesValue []byte
+ ExportPubKeyTypeValue kmsservice.KeyType
CrAndExportPubKeyValue []byte
CrAndExportPubKeyID string
CrAndExportPubKeyErr error
@@ -75,12 +76,12 @@ func (k *KeyManager) Rotate(kt kmsservice.KeyType, keyID string) (string, interf
}
// ExportPubKeyBytes will return a mocked []bytes public key.
-func (k *KeyManager) ExportPubKeyBytes(keyID string) ([]byte, error) {
+func (k *KeyManager) ExportPubKeyBytes(keyID string) ([]byte, kmsservice.KeyType, error) {
if k.ExportPubKeyBytesErr != nil {
- return nil, k.ExportPubKeyBytesErr
+ return nil, "", k.ExportPubKeyBytesErr
}
- return k.ExportPubKeyBytesValue, nil
+ return k.ExportPubKeyBytesValue, k.ExportPubKeyTypeValue, nil
}
// CreateAndExportPubKeyBytes return a mocked kid and []byte public key.
diff --git a/pkg/wallet/storage.go b/pkg/wallet/storage.go
index 2c17023f4..2513e0f9b 100644
--- a/pkg/wallet/storage.go
+++ b/pkg/wallet/storage.go
@@ -128,7 +128,7 @@ func createEDVStorageProvider(auth string, profile *profile, opts *unlockOpts) (
// getJWSEncrypter creates and returns jwe encrypter based on key manager & crypto provided
func getJWSEncrypter(kid string, keyMgr kms.KeyManager, cryptoImpl crypto.Crypto) (*jose.JWEEncrypt, error) {
- pubKeyBytes, err := keyMgr.ExportPubKeyBytes(kid)
+ pubKeyBytes, _, err := keyMgr.ExportPubKeyBytes(kid)
if err != nil {
return nil, err
}
diff --git a/test/bdd/go.mod b/test/bdd/go.mod
index e08e3eff3..22cd14a6f 100644
--- a/test/bdd/go.mod
+++ b/test/bdd/go.mod
@@ -13,10 +13,10 @@ require (
github.com/fsouza/go-dockerclient v1.6.6
github.com/google/uuid v1.1.2
github.com/gorilla/mux v1.8.0
- github.com/hyperledger/aries-framework-go v0.1.7-0.20210603210127-e57b8c94e3cf
- github.com/hyperledger/aries-framework-go/component/storage/leveldb v0.0.0-20210820175050-dcc7a225178d
- github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20210820175050-dcc7a225178d
- github.com/hyperledger/aries-framework-go/spi v0.0.0-20211203210130-e927c9ed581a
+ github.com/hyperledger/aries-framework-go v0.1.8-0.20220308060532-714cd5c18552
+ github.com/hyperledger/aries-framework-go/component/storage/leveldb v0.0.0-20220308060532-714cd5c18552
+ github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220308060532-714cd5c18552
+ github.com/hyperledger/aries-framework-go/spi v0.0.0-20220308060532-714cd5c18552
github.com/moby/sys/mount v0.2.0 // indirect
github.com/moby/term v0.0.0-20201110203204-bea5bbe245bf // indirect
github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2
@@ -48,6 +48,7 @@ require (
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/snappy v0.0.3 // indirect
github.com/google/tink/go v1.6.1-0.20210519071714-58be99b3c4d0 // indirect
+ github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220308060532-714cd5c18552 // indirect
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a // indirect
github.com/kawamuray/jsonpath v0.0.0-20201211160320-7483bafabd7e // indirect
github.com/kilic/bls12-381 v0.1.1-0.20210503002446-7b7597926c69 // indirect
diff --git a/test/bdd/go.sum b/test/bdd/go.sum
index 7f6f6141d..7324fe997 100644
--- a/test/bdd/go.sum
+++ b/test/bdd/go.sum
@@ -72,7 +72,6 @@ github.com/btcsuite/btcd v0.22.0-beta h1:LTDpDKUM5EeOFBPM8IXpinEcmZ6FWfNZbE3lfrf
github.com/btcsuite/btcd v0.22.0-beta/go.mod h1:9n5ntfhhHQBIhUvlhDvD3Qg6fRUj4jkN0VB8L8svzOA=
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
-github.com/btcsuite/btcutil v1.0.1/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts=
github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce h1:YtWJF7RHm2pYCvA5t0RPmAaLUhREsKuKd+SLhxFbFeQ=
github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o=
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg=
@@ -278,7 +277,8 @@ github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKe
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
-github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20210820175050-dcc7a225178d/go.mod h1:i40JkMHCh9cHHxSc1SYznO3xDH6ly5CE0B3vPYZVeWI=
+github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220308060532-714cd5c18552 h1:5z5ACTvbjydtD9d04Inki7gy8k1RatVqi6zhSIIE0f8=
+github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220308060532-714cd5c18552/go.mod h1:eIac5lubCy3tw6D0sTluM5U6Bw3inBwUfjX17o2U7PE=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
diff --git a/test/bdd/pkg/verifiable/verifiable_steps.go b/test/bdd/pkg/verifiable/verifiable_steps.go
index 0f313a796..565894c21 100644
--- a/test/bdd/pkg/verifiable/verifiable_steps.go
+++ b/test/bdd/pkg/verifiable/verifiable_steps.go
@@ -324,7 +324,7 @@ func (s *SDKSteps) createKeyPair(agent, proofType string) error {
return err
}
- pubKeyBytes, err := localKMS.ExportPubKeyBytes(kid)
+ pubKeyBytes, _, err := localKMS.ExportPubKeyBytes(kid)
if err != nil {
return err
}
diff --git a/test/bdd/pkg/webkms/webkms_steps.go b/test/bdd/pkg/webkms/webkms_steps.go
index 682af879f..59563a99d 100644
--- a/test/bdd/pkg/webkms/webkms_steps.go
+++ b/test/bdd/pkg/webkms/webkms_steps.go
@@ -126,7 +126,7 @@ func (c *SDKSteps) createKey(agentID, keyType string) error {
func (c *SDKSteps) exportPubKey(agentID string) error {
agent := c.bddContext.AgentCtx[agentID]
- keyBytes, err := agent.KMS().ExportPubKeyBytes(c.keyIDs[agentID])
+ keyBytes, _, err := agent.KMS().ExportPubKeyBytes(c.keyIDs[agentID])
if err != nil {
return err
}
From 4885b59806885a793eaa403818ab458e7e545a3d Mon Sep 17 00:00:00 2001
From: Firas Qutishat
Date: Thu, 10 Mar 2022 04:50:49 -0500
Subject: [PATCH 09/54] feat: add support for ed25519signature2020
Signed-off-by: Firas Qutishat
---
pkg/doc/did/doc.go | 59 +++++++--
pkg/doc/did/doc_test.go | 108 +++++++++++++---
pkg/doc/ldcontext/embed/embed_contexts.go | 7 ++
.../ed25519-signature-2020-v1.jsonld | 93 ++++++++++++++
.../public_key_verifier.go | 17 +++
.../public_key_verifier_test.go | 57 +++++++++
.../suite/ed25519signature2020/suite.go | 57 +++++++++
.../ed25519signature2020/suite_crypto_test.go | 119 ++++++++++++++++++
.../suite/ed25519signature2020/suite_test.go | 69 ++++++++++
pkg/doc/verifiable/credential_ldp_test.go | 34 +++++
pkg/doc/verifiable/credential_test.go | 2 +
pkg/doc/verifiable/embedded_proof.go | 3 +-
.../testdata/valid_credential.jsonld | 5 +-
test/bdd/go.mod | 4 +-
test/bdd/go.sum | 4 +-
15 files changed, 605 insertions(+), 33 deletions(-)
create mode 100644 pkg/doc/ldcontext/embed/third_party/digitalbazaar.github.io/ed25519-signature-2020-v1.jsonld
create mode 100644 pkg/doc/signature/suite/ed25519signature2020/public_key_verifier.go
create mode 100644 pkg/doc/signature/suite/ed25519signature2020/public_key_verifier_test.go
create mode 100644 pkg/doc/signature/suite/ed25519signature2020/suite.go
create mode 100644 pkg/doc/signature/suite/ed25519signature2020/suite_crypto_test.go
create mode 100644 pkg/doc/signature/suite/ed25519signature2020/suite_test.go
diff --git a/pkg/doc/did/doc.go b/pkg/doc/did/doc.go
index fdbcde8e7..70a4a6bfe 100644
--- a/pkg/doc/did/doc.go
+++ b/pkg/doc/did/doc.go
@@ -18,6 +18,7 @@ import (
"time"
"github.com/btcsuite/btcutil/base58"
+ "github.com/multiformats/go-multibase"
"github.com/xeipuuv/gojsonschema"
"github.com/hyperledger/aries-framework-go/pkg/doc/jose/jwk"
@@ -51,10 +52,11 @@ const (
jsonldProofPurpose = "proofPurpose"
// various public key encodings.
- jsonldPublicKeyBase58 = "publicKeyBase58"
- jsonldPublicKeyHex = "publicKeyHex"
- jsonldPublicKeyPem = "publicKeyPem"
- jsonldPublicKeyjwk = "publicKeyJwk"
+ jsonldPublicKeyBase58 = "publicKeyBase58"
+ jsonldPublicKeyMultibase = "publicKeyMultibase"
+ jsonldPublicKeyHex = "publicKeyHex"
+ jsonldPublicKeyPem = "publicKeyPem"
+ jsonldPublicKeyjwk = "publicKeyJwk"
)
var (
@@ -285,8 +287,28 @@ type VerificationMethod struct {
Value []byte
- jsonWebKey *jwk.JWK
- relativeURL bool
+ jsonWebKey *jwk.JWK
+ relativeURL bool
+ multibaseEncoding multibase.Encoding
+}
+
+// NewVerificationMethodFromBytesWithMultibase creates a new VerificationMethod based on
+// raw public key bytes with multibase.
+func NewVerificationMethodFromBytesWithMultibase(id, keyType, controller string, value []byte,
+ encoding multibase.Encoding) *VerificationMethod {
+ relativeURL := false
+ if strings.HasPrefix(id, "#") {
+ relativeURL = true
+ }
+
+ return &VerificationMethod{
+ ID: id,
+ Type: keyType,
+ Controller: controller,
+ Value: value,
+ relativeURL: relativeURL,
+ multibaseEncoding: encoding,
+ }
}
// NewVerificationMethodFromBytes creates a new VerificationMethod based on raw public key bytes.
@@ -296,6 +318,10 @@ func NewVerificationMethodFromBytes(id, keyType, controller string, value []byte
relativeURL = true
}
+ if keyType == "Ed25519VerificationKey2020" {
+ return NewVerificationMethodFromBytesWithMultibase(id, keyType, controller, value, multibase.Base58BTC)
+ }
+
return &VerificationMethod{
ID: id,
Type: keyType,
@@ -827,6 +853,18 @@ func decodeVM(vm *VerificationMethod, rawPK map[string]interface{}) error {
return nil
}
+ if stringEntry(rawPK[jsonldPublicKeyMultibase]) != "" {
+ multibaseEncoding, value, err := multibase.Decode(stringEntry(rawPK[jsonldPublicKeyMultibase]))
+ if err != nil {
+ return err
+ }
+
+ vm.Value = value
+ vm.multibaseEncoding = multibaseEncoding
+
+ return nil
+ }
+
if stringEntry(rawPK[jsonldPublicKeyHex]) != "" {
value, err := hex.DecodeString(stringEntry(rawPK[jsonldPublicKeyHex]))
if err != nil {
@@ -1309,13 +1347,20 @@ func populateRawVerificationMethod(context, didID, baseURI string,
}
}
- if vm.jsonWebKey != nil {
+ if vm.jsonWebKey != nil { //nolint: gocritic
jwkBytes, err := json.Marshal(vm.jsonWebKey)
if err != nil {
return nil, err
}
rawVM[jsonldPublicKeyjwk] = json.RawMessage(jwkBytes)
+ } else if vm.Type == "Ed25519VerificationKey2020" {
+ var err error
+
+ rawVM[jsonldPublicKeyMultibase], err = multibase.Encode(vm.multibaseEncoding, vm.Value)
+ if err != nil {
+ return nil, err
+ }
} else if vm.Value != nil {
rawVM[jsonldPublicKeyBase58] = base58.Encode(vm.Value)
}
diff --git a/pkg/doc/did/doc_test.go b/pkg/doc/did/doc_test.go
index ab7879483..71db2f52f 100644
--- a/pkg/doc/did/doc_test.go
+++ b/pkg/doc/did/doc_test.go
@@ -27,6 +27,7 @@ import (
"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"
)
@@ -42,10 +43,12 @@ FQIDAQAB
-----END PUBLIC KEY-----`
const (
- did = "did:method:abc"
- creator = did + "#key-1"
- keyType = "Ed25519VerificationKey2018"
- signatureType = "Ed25519Signature2018"
+ did = "did:method:abc"
+ creator = did + "#key-1"
+ keyType = "Ed25519VerificationKey2018"
+ keyType2020 = "Ed25519VerificationKey2020"
+ signatureType = "Ed25519Signature2018"
+ signatureType2020 = "Ed25519Signature2020"
)
const (
@@ -479,10 +482,10 @@ func TestPublicKeys(t *testing.T) {
if len(raw.PublicKey) != 0 {
delete(raw.PublicKey[1], jsonldPublicKeyPem)
- raw.PublicKey[1]["publicKeyMultibase"] = wrongDataMsg
+ raw.PublicKey[1]["publicKeyMultibase1"] = wrongDataMsg
} else {
delete(raw.VerificationMethod[1], jsonldPublicKeyPem)
- raw.VerificationMethod[1]["publicKeyMultibase"] = wrongDataMsg
+ raw.VerificationMethod[1]["publicKeyMultibase1"] = wrongDataMsg
}
bytes, err := json.Marshal(raw)
@@ -1138,6 +1141,46 @@ func TestVerifyProof(t *testing.T) {
}
}
+func TestVerifyProofWithEd25519signature2020(t *testing.T) {
+ docs := []string{validDoc}
+ for _, d := range docs {
+ pubKey, privKey, err := ed25519.GenerateKey(rand.Reader)
+ if err != nil {
+ panic(err)
+ }
+
+ signedDoc := createSignedDidDocumentWithEd25519signature2020(t, privKey, pubKey)
+
+ s := ed25519signature2020.New(suite.WithVerifier(ed25519signature2020.NewPublicKeyVerifier()))
+
+ // happy path - valid signed document
+ doc, err := ParseDocument(signedDoc)
+ require.Nil(t, err)
+ require.NotNil(t, doc)
+ err = doc.VerifyProof([]verifier.SignatureSuite{s}, ldtestutil.WithDocumentLoader(t))
+ require.NoError(t, err)
+
+ // error - no suites are passed, verifier is not created
+ err = doc.VerifyProof([]verifier.SignatureSuite{}, ldtestutil.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))
+ 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))
+ require.Equal(t, ErrProofNotFound, err)
+ require.Contains(t, err.Error(), "proof not found")
+ }
+}
+
func TestDidKeyResolver_Resolve(t *testing.T) {
// error - key not found
keyResolver := didKeyResolver{}
@@ -1661,43 +1704,70 @@ func TestDoc_SerializeInterop(t *testing.T) {
require.Equal(t, docJSON, docInteropJSON)
}
-func createDidDocumentWithSigningKey(pubKey []byte) *Doc {
+func createDidDocumentWithSigningKey(vm VerificationMethod, context []string) *Doc { //nolint: gocritic
+ createdTime := time.Now()
+
+ didDoc := &Doc{
+ Context: context,
+ ID: did,
+ VerificationMethod: []VerificationMethod{vm},
+ Created: &createdTime,
+ }
+
+ return didDoc
+}
+
+func createSignedDidDocument(t *testing.T, privKey, pubKey []byte) []byte {
const (
didContext = "https://w3id.org/did/v1"
securityContext = "https://w3id.org/security/v1"
)
- signingKey := VerificationMethod{
+ vm := VerificationMethod{
ID: creator,
Type: keyType,
Controller: did,
Value: pubKey,
}
- createdTime := time.Now()
+ didDoc := createDidDocumentWithSigningKey(vm, []string{didContext, securityContext})
- didDoc := &Doc{
- Context: []string{didContext, securityContext},
- ID: did,
- VerificationMethod: []VerificationMethod{signingKey},
- Created: &createdTime,
+ jsonDoc, err := didDoc.JSONBytes()
+ require.NoError(t, err)
+
+ context := &signer.Context{
+ Creator: creator,
+ SignatureType: signatureType,
}
- return didDoc
+ s := signer.New(ed25519signature2018.New(
+ suite.WithSigner(getSigner(privKey))))
+
+ signedDoc, err := s.Sign(context, jsonDoc, ldtestutil.WithDocumentLoader(t))
+ require.NoError(t, err)
+
+ return signedDoc
}
-func createSignedDidDocument(t *testing.T, privKey, pubKey []byte) []byte {
- didDoc := createDidDocumentWithSigningKey(pubKey)
+func createSignedDidDocumentWithEd25519signature2020(t *testing.T, privKey, pubKey []byte) []byte {
+ const (
+ didContext = "https://w3id.org/did/v1"
+ securityContext = "https://w3id.org/security/suites/ed25519-2020/v1"
+ )
+
+ vm := NewVerificationMethodFromBytes(creator, keyType2020, did, pubKey)
+
+ didDoc := createDidDocumentWithSigningKey(*vm, []string{didContext, securityContext})
jsonDoc, err := didDoc.JSONBytes()
require.NoError(t, err)
context := &signer.Context{
Creator: creator,
- SignatureType: signatureType,
+ SignatureType: signatureType2020,
}
- s := signer.New(ed25519signature2018.New(
+ s := signer.New(ed25519signature2020.New(
suite.WithSigner(getSigner(privKey))))
signedDoc, err := s.Sign(context, jsonDoc, ldtestutil.WithDocumentLoader(t))
diff --git a/pkg/doc/ldcontext/embed/embed_contexts.go b/pkg/doc/ldcontext/embed/embed_contexts.go
index 692b31c5a..a4b1f980a 100644
--- a/pkg/doc/ldcontext/embed/embed_contexts.go
+++ b/pkg/doc/ldcontext/embed/embed_contexts.go
@@ -46,6 +46,8 @@ var (
credentialFulfillment []byte
//go:embed third_party/identity.foundation/credential-application.jsonld
credentialApplication []byte
+ //go:embed third_party/digitalbazaar.github.io/ed25519-signature-2020-v1.jsonld
+ ed255192020 []byte
)
// Contexts contains JSON-LD contexts embedded into a Go binary.
@@ -140,4 +142,9 @@ var Contexts = []ldcontext.Document{ //nolint:gochecknoglobals
DocumentURL: "https://identity.foundation/credential-manifest/application/v1",
Content: credentialApplication,
},
+ {
+ URL: "https://w3id.org/security/suites/ed25519-2020/v1",
+ DocumentURL: "https://digitalbazaar.github.io/ed25519-signature-2020-context/contexts/ed25519-signature-2020-v1.jsonld", //nolint: lll
+ Content: ed255192020,
+ },
}
diff --git a/pkg/doc/ldcontext/embed/third_party/digitalbazaar.github.io/ed25519-signature-2020-v1.jsonld b/pkg/doc/ldcontext/embed/third_party/digitalbazaar.github.io/ed25519-signature-2020-v1.jsonld
new file mode 100644
index 000000000..b74da8c0b
--- /dev/null
+++ b/pkg/doc/ldcontext/embed/third_party/digitalbazaar.github.io/ed25519-signature-2020-v1.jsonld
@@ -0,0 +1,93 @@
+{
+ "@context": {
+ "id": "@id",
+ "type": "@type",
+ "@protected": true,
+ "proof": {
+ "@id": "https://w3id.org/security#proof",
+ "@type": "@id",
+ "@container": "@graph"
+ },
+ "Ed25519VerificationKey2020": {
+ "@id": "https://w3id.org/security#Ed25519VerificationKey2020",
+ "@context": {
+ "@protected": true,
+ "id": "@id",
+ "type": "@type",
+ "controller": {
+ "@id": "https://w3id.org/security#controller",
+ "@type": "@id"
+ },
+ "revoked": {
+ "@id": "https://w3id.org/security#revoked",
+ "@type": "http://www.w3.org/2001/XMLSchema#dateTime"
+ },
+ "publicKeyMultibase": {
+ "@id": "https://w3id.org/security#publicKeyMultibase",
+ "@type": "https://w3id.org/security#multibase"
+ }
+ }
+ },
+ "Ed25519Signature2020": {
+ "@id": "https://w3id.org/security#Ed25519Signature2020",
+ "@context": {
+ "@protected": true,
+ "id": "@id",
+ "type": "@type",
+ "challenge": "https://w3id.org/security#challenge",
+ "created": {
+ "@id": "http://purl.org/dc/terms/created",
+ "@type": "http://www.w3.org/2001/XMLSchema#dateTime"
+ },
+ "domain": "https://w3id.org/security#domain",
+ "expires": {
+ "@id": "https://w3id.org/security#expiration",
+ "@type": "http://www.w3.org/2001/XMLSchema#dateTime"
+ },
+ "nonce": "https://w3id.org/security#nonce",
+ "proofPurpose": {
+ "@id": "https://w3id.org/security#proofPurpose",
+ "@type": "@vocab",
+ "@context": {
+ "@protected": true,
+ "id": "@id",
+ "type": "@type",
+ "assertionMethod": {
+ "@id": "https://w3id.org/security#assertionMethod",
+ "@type": "@id",
+ "@container": "@set"
+ },
+ "authentication": {
+ "@id": "https://w3id.org/security#authenticationMethod",
+ "@type": "@id",
+ "@container": "@set"
+ },
+ "capabilityInvocation": {
+ "@id": "https://w3id.org/security#capabilityInvocationMethod",
+ "@type": "@id",
+ "@container": "@set"
+ },
+ "capabilityDelegation": {
+ "@id": "https://w3id.org/security#capabilityDelegationMethod",
+ "@type": "@id",
+ "@container": "@set"
+ },
+ "keyAgreement": {
+ "@id": "https://w3id.org/security#keyAgreementMethod",
+ "@type": "@id",
+ "@container": "@set"
+ }
+ }
+ },
+ "proofValue": {
+ "@id": "https://w3id.org/security#proofValue",
+ "@type": "https://w3id.org/security#multibase"
+ },
+ "verificationMethod": {
+ "@id": "https://w3id.org/security#verificationMethod",
+ "@type": "@id"
+ }
+ }
+ }
+ }
+}
diff --git a/pkg/doc/signature/suite/ed25519signature2020/public_key_verifier.go b/pkg/doc/signature/suite/ed25519signature2020/public_key_verifier.go
new file mode 100644
index 000000000..783689137
--- /dev/null
+++ b/pkg/doc/signature/suite/ed25519signature2020/public_key_verifier.go
@@ -0,0 +1,17 @@
+/*
+Copyright SecureKey Technologies Inc. All Rights Reserved.
+
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package ed25519signature2020
+
+import (
+ "github.com/hyperledger/aries-framework-go/pkg/doc/signature/verifier"
+)
+
+// NewPublicKeyVerifier creates a signature verifier that verifies a Ed25519 signature
+// taking Ed25519 public key bytes as input.
+func NewPublicKeyVerifier() *verifier.PublicKeyVerifier {
+ return verifier.NewPublicKeyVerifier(verifier.NewEd25519SignatureVerifier())
+}
diff --git a/pkg/doc/signature/suite/ed25519signature2020/public_key_verifier_test.go b/pkg/doc/signature/suite/ed25519signature2020/public_key_verifier_test.go
new file mode 100644
index 000000000..2a10489b5
--- /dev/null
+++ b/pkg/doc/signature/suite/ed25519signature2020/public_key_verifier_test.go
@@ -0,0 +1,57 @@
+/*
+Copyright SecureKey Technologies Inc. All Rights Reserved.
+
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package ed25519signature2020
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/require"
+
+ "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto"
+ "github.com/hyperledger/aries-framework-go/pkg/doc/signature/verifier"
+ "github.com/hyperledger/aries-framework-go/pkg/doc/util/signature"
+ kmsapi "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"
+)
+
+func TestPublicKeyVerifier_Verify(t *testing.T) {
+ signer, err := newCryptoSigner(kmsapi.ED25519Type)
+ require.NoError(t, err)
+
+ msg := []byte("test message")
+
+ msgSig, err := signer.Sign(msg)
+ require.NoError(t, err)
+
+ pubKey := &verifier.PublicKey{
+ Type: kmsapi.ED25519,
+ Value: signer.PublicKeyBytes(),
+ }
+ v := NewPublicKeyVerifier()
+
+ err = v.Verify(pubKey, msg, msgSig)
+ require.NoError(t, err)
+}
+
+func newCryptoSigner(keyType kmsapi.KeyType) (signature.Signer, error) {
+ p := mockkms.NewProviderForKMS(storage.NewMockStoreProvider(), &noop.NoLock{})
+
+ localKMS, err := localkms.New("local-lock://custom/master/key/", p)
+ if err != nil {
+ return nil, err
+ }
+
+ tinkCrypto, err := tinkcrypto.New()
+ if err != nil {
+ return nil, err
+ }
+
+ return signature.NewCryptoSigner(tinkCrypto, localKMS, keyType)
+}
diff --git a/pkg/doc/signature/suite/ed25519signature2020/suite.go b/pkg/doc/signature/suite/ed25519signature2020/suite.go
new file mode 100644
index 000000000..bb99f3d43
--- /dev/null
+++ b/pkg/doc/signature/suite/ed25519signature2020/suite.go
@@ -0,0 +1,57 @@
+/*
+Copyright SecureKey Technologies Inc. All Rights Reserved.
+SPDX-License-Identifier: Apache-2.0
+*/
+
+// Package ed25519signature2020 implements the Ed25519Signature2020 signature suite
+// for the Linked Data Signatures [LD-SIGNATURES] specification.
+// It uses the RDF Dataset Normalization Algorithm [RDF-DATASET-NORMALIZATION]
+// to transform the input document into its canonical form.
+// It uses SHA-256 [RFC6234] as the message digest algorithm and
+// Ed25519 [ED25519] as the signature algorithm.
+package ed25519signature2020
+
+import (
+ "crypto/sha256"
+
+ "github.com/hyperledger/aries-framework-go/pkg/doc/signature/jsonld"
+ "github.com/hyperledger/aries-framework-go/pkg/doc/signature/suite"
+)
+
+// Suite implements ed25519 signature suite.
+type Suite struct {
+ suite.SignatureSuite
+ jsonldProcessor *jsonld.Processor
+}
+
+const (
+ // SignatureType is the signature type for ed25519 keys.
+ SignatureType = "Ed25519Signature2020"
+ rdfDataSetAlg = "URDNA2015"
+)
+
+// New an instance of ed25519 signature suite.
+func New(opts ...suite.Opt) *Suite {
+ s := &Suite{jsonldProcessor: jsonld.NewProcessor(rdfDataSetAlg)}
+
+ suite.InitSuiteOptions(&s.SignatureSuite, opts...)
+
+ return s
+}
+
+// GetCanonicalDocument will return normalized/canonical version of the document
+// Ed25519Signature2020 signature SignatureSuite uses RDF Dataset Normalization as canonicalization algorithm.
+func (s *Suite) GetCanonicalDocument(doc map[string]interface{}, opts ...jsonld.ProcessorOpts) ([]byte, error) {
+ return s.jsonldProcessor.GetCanonicalDocument(doc, opts...)
+}
+
+// GetDigest returns document digest.
+func (s *Suite) GetDigest(doc []byte) []byte {
+ digest := sha256.Sum256(doc)
+ return digest[:]
+}
+
+// Accept will accept only ed25519 signature type.
+func (s *Suite) Accept(t string) bool {
+ return t == SignatureType
+}
diff --git a/pkg/doc/signature/suite/ed25519signature2020/suite_crypto_test.go b/pkg/doc/signature/suite/ed25519signature2020/suite_crypto_test.go
new file mode 100644
index 000000000..662f218d7
--- /dev/null
+++ b/pkg/doc/signature/suite/ed25519signature2020/suite_crypto_test.go
@@ -0,0 +1,119 @@
+/*
+Copyright SecureKey Technologies Inc. All Rights Reserved.
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package ed25519signature2020
+
+import (
+ "errors"
+ "fmt"
+ "testing"
+
+ "github.com/google/tink/go/keyset"
+
+ "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto"
+ "github.com/hyperledger/aries-framework-go/pkg/doc/signature/suite"
+ sigverifier "github.com/hyperledger/aries-framework-go/pkg/doc/signature/verifier"
+ kmsapi "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"
+)
+
+func TestNewCryptoSignerAndVerifier(t *testing.T) {
+ lKMS := createKMS()
+
+ kid, kh := createKeyHandle(lKMS, kmsapi.ED25519Type)
+
+ tinkCrypto, err := tinkcrypto.New()
+ if err != nil {
+ panic("failed to create tinkcrypto")
+ }
+
+ doc := []byte("test doc")
+
+ suiteSigner := suite.NewCryptoSigner(tinkCrypto, kh)
+ suiteVerifier := suite.NewCryptoVerifier(&Crypto{
+ Crypto: tinkCrypto,
+ localKMS: lKMS,
+ })
+
+ ss := New(suite.WithSigner(suiteSigner), suite.WithVerifier(suiteVerifier))
+
+ docSig, err := ss.Sign(doc)
+ if err != nil {
+ panic("failed to create a signature")
+ }
+
+ pubKeyBytes, _, err := lKMS.ExportPubKeyBytes(kid)
+ if err != nil {
+ panic("failed to export public key bytes")
+ }
+
+ pubKey := &sigverifier.PublicKey{
+ Type: kmsapi.ED25519,
+ Value: pubKeyBytes,
+ }
+
+ err = ss.Verify(pubKey, doc, docSig)
+ if err != nil {
+ panic("failed to verify signature")
+ }
+}
+
+// LocalCrypto defines a verifier which is based on Local KMS and Crypto
+// which uses keyset.Handle as input for verification.
+type Crypto struct {
+ *tinkcrypto.Crypto
+ localKMS *localkms.LocalKMS
+}
+
+func (t *Crypto) Verify(sig, msg []byte, kh interface{}) error {
+ pubKey, ok := kh.(*sigverifier.PublicKey)
+ if !ok {
+ return errors.New("bad key handle format")
+ }
+
+ kmsKeyType, err := mapKeyTypeToKMS(pubKey.Type)
+ if err != nil {
+ return err
+ }
+
+ handle, err := t.localKMS.PubKeyBytesToHandle(pubKey.Value, kmsKeyType)
+ if err != nil {
+ return err
+ }
+
+ return t.Crypto.Verify(sig, msg, handle)
+}
+
+func createKeyHandle(kms *localkms.LocalKMS, keyType kmsapi.KeyType) (string, *keyset.Handle) {
+ kid, kh, err := kms.Create(keyType)
+ if err != nil {
+ panic(err)
+ }
+
+ return kid, kh.(*keyset.Handle)
+}
+
+func createKMS() *localkms.LocalKMS {
+ p := mockkms.NewProviderForKMS(storage.NewMockStoreProvider(), &noop.NoLock{})
+
+ k, err := localkms.New("local-lock://custom/master/key/", p)
+ if err != nil {
+ panic(err)
+ }
+
+ return k
+}
+
+func mapKeyTypeToKMS(t string) (kmsapi.KeyType, error) {
+ switch t {
+ case kmsapi.ED25519, "Ed25519VerificationKey2020":
+ return kmsapi.ED25519Type, nil
+ default:
+ return "", fmt.Errorf("unsupported key type: %s", t)
+ }
+}
diff --git a/pkg/doc/signature/suite/ed25519signature2020/suite_test.go b/pkg/doc/signature/suite/ed25519signature2020/suite_test.go
new file mode 100644
index 000000000..bf1315875
--- /dev/null
+++ b/pkg/doc/signature/suite/ed25519signature2020/suite_test.go
@@ -0,0 +1,69 @@
+/*
+Copyright SecureKey Technologies Inc. All Rights Reserved.
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package ed25519signature2020
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/require"
+)
+
+func TestSignatureSuite_GetCanonicalDocument(t *testing.T) {
+ doc, err := New().GetCanonicalDocument(getDefaultDoc())
+ require.NoError(t, err)
+ require.NotEmpty(t, doc)
+ require.Equal(t, test28Result, string(doc))
+}
+
+func TestSignatureSuite_GetDigest(t *testing.T) {
+ digest := New().GetDigest([]byte("test doc"))
+ require.NotNil(t, digest)
+}
+
+func TestSignatureSuite_Accept(t *testing.T) {
+ ss := New()
+ accepted := ss.Accept("Ed25519Signature2020")
+ require.True(t, accepted)
+
+ accepted = ss.Accept("RsaSignature2018")
+ require.False(t, accepted)
+}
+
+func getDefaultDoc() map[string]interface{} {
+ // this JSON-LD document was taken from http://json-ld.org/test-suite/tests/toRdf-0028-in.jsonld
+ doc := map[string]interface{}{
+ "@context": map[string]interface{}{
+ "sec": "http://purl.org/security#",
+ "xsd": "http://www.w3.org/2001/XMLSchema#",
+ "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
+ "dc": "http://purl.org/dc/terms/",
+ "sec:signer": map[string]interface{}{"@type": "@id"},
+ "dc:created": map[string]interface{}{"@type": "xsd:dateTime"},
+ },
+ "@id": "http://example.org/sig1",
+ "@type": []interface{}{"rdf:Graph", "sec:SignedGraph"},
+ "dc:created": "2011-09-23T20:21:34Z",
+ "sec:signer": "http://payswarm.example.com/i/john/keys/5",
+ "sec:signatureValue": "OGQzNGVkMzVm4NTIyZTkZDYMmMzQzNmExMgoYzI43Q3ODIyOWM32NjI=",
+ "@graph": map[string]interface{}{
+ "@id": "http://example.org/fact1",
+ "dc:title": "Hello World!",
+ },
+ }
+
+ return doc
+}
+
+// taken from test 28 report https://json-ld.org/test-suite/reports/#test_30bc80ba056257df8a196e8f65c097fc
+
+// nolint
+const test28Result = ` "Hello World!" .
+ "2011-09-23T20:21:34Z"^^ .
+ "OGQzNGVkMzVm4NTIyZTkZDYMmMzQzNmExMgoYzI43Q3ODIyOWM32NjI=" .
+ .
+ .
+ .
+`
diff --git a/pkg/doc/verifiable/credential_ldp_test.go b/pkg/doc/verifiable/credential_ldp_test.go
index 4a27526cd..ec47b8b56 100644
--- a/pkg/doc/verifiable/credential_ldp_test.go
+++ b/pkg/doc/verifiable/credential_ldp_test.go
@@ -30,6 +30,7 @@ import (
"github.com/hyperledger/aries-framework-go/pkg/doc/signature/suite/bbsblssignatureproof2020"
"github.com/hyperledger/aries-framework-go/pkg/doc/signature/suite/ecdsasecp256k1signature2019"
"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/suite/jsonwebsignature2020"
sigverifier "github.com/hyperledger/aries-framework-go/pkg/doc/signature/verifier"
"github.com/hyperledger/aries-framework-go/pkg/kms"
@@ -69,6 +70,39 @@ func TestParseCredentialFromLinkedDataProof_Ed25519Signature2018(t *testing.T) {
r.Equal(vc, vcWithLdp)
}
+func TestParseCredentialFromLinkedDataProof_Ed25519Signature2020(t *testing.T) {
+ r := require.New(t)
+
+ signer, err := newCryptoSigner(kms.ED25519Type)
+ r.NoError(err)
+
+ sigSuite := ed25519signature2020.New(
+ suite.WithSigner(signer),
+ suite.WithVerifier(ed25519signature2020.NewPublicKeyVerifier()))
+
+ ldpContext := &LinkedDataProofContext{
+ SignatureType: "Ed25519Signature2020",
+ SignatureRepresentation: SignatureProofValue,
+ Suite: sigSuite,
+ VerificationMethod: "did:example:123456#key1",
+ }
+
+ vc, err := parseTestCredential(t, []byte(validCredential))
+ r.NoError(err)
+
+ err = vc.AddLinkedDataProof(ldpContext, jsonldsig.WithDocumentLoader(createTestDocumentLoader(t)))
+ r.NoError(err)
+
+ vcBytes, err := json.Marshal(vc)
+ r.NoError(err)
+
+ vcWithLdp, err := parseTestCredential(t, vcBytes,
+ WithEmbeddedSignatureSuites(sigSuite),
+ WithPublicKeyFetcher(SingleKey(signer.PublicKeyBytes(), kms.ED25519)))
+ r.NoError(err)
+ r.Equal(vc, vcWithLdp)
+}
+
//nolint:lll
func TestParseCredentialFromLinkedDataProof_JSONLD_Validation(t *testing.T) {
r := require.New(t)
diff --git a/pkg/doc/verifiable/credential_test.go b/pkg/doc/verifiable/credential_test.go
index ab8fb7b3e..8c3658e6b 100644
--- a/pkg/doc/verifiable/credential_test.go
+++ b/pkg/doc/verifiable/credential_test.go
@@ -65,6 +65,7 @@ func TestParseCredential(t *testing.T) {
"https://www.w3.org/2018/credentials/examples/v1",
"https://w3id.org/security/jws/v1",
"https://trustbloc.github.io/context/vc/examples-v1.jsonld",
+ "https://w3id.org/security/suites/ed25519-2020/v1",
}, vc.Context)
// validate id
@@ -927,6 +928,7 @@ func TestCustomCredentialJsonSchemaValidator2018(t *testing.T) {
"https://www.w3.org/2018/credentials/examples/v1",
"https://w3id.org/security/jws/v1",
"https://trustbloc.github.io/context/vc/examples-v1.jsonld",
+ "https://w3id.org/security/suites/ed25519-2020/v1",
}, []string{
"VerifiableCredential",
"UniversityDegreeCredential",
diff --git a/pkg/doc/verifiable/embedded_proof.go b/pkg/doc/verifiable/embedded_proof.go
index c4f82f1e0..0b290aab4 100644
--- a/pkg/doc/verifiable/embedded_proof.go
+++ b/pkg/doc/verifiable/embedded_proof.go
@@ -23,6 +23,7 @@ import (
const (
ed25519Signature2018 = "Ed25519Signature2018"
+ ed25519Signature2020 = "Ed25519Signature2020"
jsonWebSignature2020 = "JsonWebSignature2020"
ecdsaSecp256k1Signature2019 = "EcdsaSecp256k1Signature2019"
bbsBlsSignature2020 = "BbsBlsSignature2020"
@@ -38,7 +39,7 @@ func getProofType(proofMap map[string]interface{}) (string, error) {
proofTypeStr := safeStringValue(proofType)
switch proofTypeStr {
case ed25519Signature2018, jsonWebSignature2020, ecdsaSecp256k1Signature2019,
- bbsBlsSignature2020, bbsBlsSignatureProof2020:
+ bbsBlsSignature2020, bbsBlsSignatureProof2020, ed25519Signature2020:
return proofTypeStr, nil
default:
return "", fmt.Errorf("unsupported proof type: %s", proofType)
diff --git a/pkg/doc/verifiable/testdata/valid_credential.jsonld b/pkg/doc/verifiable/testdata/valid_credential.jsonld
index 22419a2e7..97b03e90a 100644
--- a/pkg/doc/verifiable/testdata/valid_credential.jsonld
+++ b/pkg/doc/verifiable/testdata/valid_credential.jsonld
@@ -3,7 +3,8 @@
"https://www.w3.org/2018/credentials/v1",
"https://www.w3.org/2018/credentials/examples/v1",
"https://w3id.org/security/jws/v1",
- "https://trustbloc.github.io/context/vc/examples-v1.jsonld"
+ "https://trustbloc.github.io/context/vc/examples-v1.jsonld",
+ "https://w3id.org/security/suites/ed25519-2020/v1"
],
"id": "http://example.edu/credentials/1872",
"type": "VerifiableCredential",
@@ -64,4 +65,4 @@
"id": "https://example.edu/refresh/3732",
"type": "ManualRefreshService2018"
}
-}
\ No newline at end of file
+}
diff --git a/test/bdd/go.mod b/test/bdd/go.mod
index 22cd14a6f..f15dc2760 100644
--- a/test/bdd/go.mod
+++ b/test/bdd/go.mod
@@ -48,7 +48,7 @@ require (
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/snappy v0.0.3 // indirect
github.com/google/tink/go v1.6.1-0.20210519071714-58be99b3c4d0 // indirect
- github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220308060532-714cd5c18552 // indirect
+ github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220217153004-1622c70e5767 // indirect
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a // indirect
github.com/kawamuray/jsonpath v0.0.0-20201211160320-7483bafabd7e // indirect
github.com/kilic/bls12-381 v0.1.1-0.20210503002446-7b7597926c69 // indirect
@@ -86,7 +86,7 @@ require (
go.opencensus.io v0.22.5 // indirect
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e // indirect
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a // indirect
- golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect
+ golang.org/x/sys v0.0.0-20210910150752-751e447fb3d0 // indirect
google.golang.org/protobuf v1.27.1 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
)
diff --git a/test/bdd/go.sum b/test/bdd/go.sum
index 7324fe997..b64c030f9 100644
--- a/test/bdd/go.sum
+++ b/test/bdd/go.sum
@@ -277,7 +277,6 @@ github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKe
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
-github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220308060532-714cd5c18552 h1:5z5ACTvbjydtD9d04Inki7gy8k1RatVqi6zhSIIE0f8=
github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220308060532-714cd5c18552/go.mod h1:eIac5lubCy3tw6D0sTluM5U6Bw3inBwUfjX17o2U7PE=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
@@ -637,8 +636,9 @@ golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20201211090839-8ad439b19e0f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210910150752-751e447fb3d0 h1:xrCZDmdtoloIiooiA9q0OQb9r8HejIHYoHGhGCe1pGg=
+golang.org/x/sys v0.0.0-20210910150752-751e447fb3d0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
From a2739910cc29765f6a73de53f9d6c6c2a6a0f1e6 Mon Sep 17 00:00:00 2001
From: Firas Qutishat
Date: Fri, 11 Mar 2022 12:47:14 -0500
Subject: [PATCH 10/54] chore: add ed25519Signature2020 to embedded proof
Signed-off-by: Firas Qutishat
---
pkg/doc/verifiable/embedded_proof.go | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/pkg/doc/verifiable/embedded_proof.go b/pkg/doc/verifiable/embedded_proof.go
index 0b290aab4..e548c47c6 100644
--- a/pkg/doc/verifiable/embedded_proof.go
+++ b/pkg/doc/verifiable/embedded_proof.go
@@ -17,6 +17,7 @@ import (
"github.com/hyperledger/aries-framework-go/pkg/doc/signature/suite/bbsblssignatureproof2020"
"github.com/hyperledger/aries-framework-go/pkg/doc/signature/suite/ecdsasecp256k1signature2019"
"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/suite/jsonwebsignature2020"
"github.com/hyperledger/aries-framework-go/pkg/doc/signature/verifier"
)
@@ -102,6 +103,7 @@ func checkEmbeddedProof(docBytes []byte, opts *embeddedProofCheckOpts) ([]byte,
return docBytes, nil
}
+// nolint:gocyclo
func getSuites(proofs []map[string]interface{}, opts *embeddedProofCheckOpts) ([]verifier.SignatureSuite, error) {
ldpSuites := opts.ldpSuites
@@ -116,6 +118,9 @@ func getSuites(proofs []map[string]interface{}, opts *embeddedProofCheckOpts) ([
case ed25519Signature2018:
ldpSuites = append(ldpSuites, ed25519signature2018.New(
suite.WithVerifier(ed25519signature2018.NewPublicKeyVerifier())))
+ case ed25519Signature2020:
+ ldpSuites = append(ldpSuites, ed25519signature2020.New(
+ suite.WithVerifier(ed25519signature2020.NewPublicKeyVerifier())))
case jsonWebSignature2020:
ldpSuites = append(ldpSuites, jsonwebsignature2020.New(
suite.WithVerifier(jsonwebsignature2020.NewPublicKeyVerifier())))
From 823d9f33ec3f6ddcc49f96d95ba16fae6b2122e9 Mon Sep 17 00:00:00 2001
From: Firas Qutishat
Date: Fri, 18 Mar 2022 10:26:30 -0400
Subject: [PATCH 11/54] fix: ECDSASignatureVerifier
Signed-off-by: Firas Qutishat
---
.../signature/verifier/public_key_verifier.go | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/pkg/doc/signature/verifier/public_key_verifier.go b/pkg/doc/signature/verifier/public_key_verifier.go
index 536479888..3197a3c1f 100644
--- a/pkg/doc/signature/verifier/public_key_verifier.go
+++ b/pkg/doc/signature/verifier/public_key_verifier.go
@@ -13,6 +13,7 @@ import (
"crypto/elliptic"
"crypto/rsa"
"crypto/x509"
+ "encoding/asn1"
"errors"
"fmt"
"math/big"
@@ -256,7 +257,7 @@ func (sv *ECDSASignatureVerifier) Verify(pubKey *PublicKey, msg, signature []byt
return errors.New("ecdsa: invalid public key type")
}
- if len(signature) != 2*ec.keySize {
+ if len(signature) < 2*ec.keySize {
return errors.New("ecdsa: invalid signature size")
}
@@ -272,6 +273,19 @@ func (sv *ECDSASignatureVerifier) Verify(pubKey *PublicKey, msg, signature []byt
r := big.NewInt(0).SetBytes(signature[:ec.keySize])
s := big.NewInt(0).SetBytes(signature[ec.keySize:])
+ if len(signature) > 2*ec.keySize {
+ var esig struct {
+ R, S *big.Int
+ }
+
+ if _, err := asn1.Unmarshal(signature, &esig); err != nil {
+ return err
+ }
+
+ r = esig.R
+ s = esig.S
+ }
+
verified := ecdsa.Verify(ecdsaPubKey, hash, r, s)
if !verified {
return errors.New("ecdsa: invalid signature")
From e9ecc512da8669609b07cdb86e2a0c709f23245c Mon Sep 17 00:00:00 2001
From: Firas Qutishat
Date: Tue, 22 Mar 2022 04:27:23 -0400
Subject: [PATCH 12/54] fix: remove batch store in ld store
Signed-off-by: Firas Qutishat
---
pkg/store/ld/context_store.go | 18 +++---------------
pkg/store/ld/context_store_test.go | 5 ++---
2 files changed, 5 insertions(+), 18 deletions(-)
diff --git a/pkg/store/ld/context_store.go b/pkg/store/ld/context_store.go
index 1e8296f09..821382356 100644
--- a/pkg/store/ld/context_store.go
+++ b/pkg/store/ld/context_store.go
@@ -209,27 +209,15 @@ func getRemoteDocumentBytes(d ldcontext.Document) ([]byte, error) {
// save stores contexts into the underlying storage.
func save(store storage.Store, contexts []ldcontext.Document) error {
- var ops []storage.Operation
-
for _, c := range contexts {
b, err := getRemoteDocumentBytes(c)
if err != nil {
return fmt.Errorf("get remote document bytes: %w", err)
}
- ops = append(ops, storage.Operation{
- Key: c.URL,
- Value: b,
- Tags: []storage.Tag{{Name: ContextRecordTag}},
- })
- }
-
- if len(ops) == 0 {
- return nil
- }
-
- if err := store.Batch(ops); err != nil {
- return fmt.Errorf("store batch of contexts: %w", err)
+ if err := store.Put(c.URL, b, storage.Tag{Name: ContextRecordTag}); err != nil {
+ return fmt.Errorf("store context: %w", err)
+ }
}
return nil
diff --git a/pkg/store/ld/context_store_test.go b/pkg/store/ld/context_store_test.go
index a51b5c5a8..b89d272ea 100644
--- a/pkg/store/ld/context_store_test.go
+++ b/pkg/store/ld/context_store_test.go
@@ -186,7 +186,6 @@ func TestContextStoreImpl_Import(t *testing.T) {
err = contextStore.Import(contexts)
require.NoError(t, err)
- require.Equal(t, 1, store.BatchSize)
assertContextInStore(t, store, sampleContextURL, "updated-context")
})
@@ -261,14 +260,14 @@ func TestContextStoreImpl_Import(t *testing.T) {
t.Run("Fail to store batch of context documents", func(t *testing.T) {
storageProvider := mockstorage.NewMockStoreProvider()
- storageProvider.Store.ErrBatch = errors.New("batch error")
+ storageProvider.Store.ErrPut = errors.New("error")
contextStore, err := ld.NewContextStore(storageProvider)
require.NoError(t, err)
err = contextStore.Import(embed.Contexts)
require.Error(t, err)
- require.Contains(t, err.Error(), "store batch of contexts")
+ require.Contains(t, err.Error(), "store context: error")
})
}
From 18c87667df1977606c8b6d708e9f7e55ed9f2d70 Mon Sep 17 00:00:00 2001
From: Baha <29608896+Baha-sk@users.noreply.github.com>
Date: Thu, 24 Mar 2022 16:15:31 -0400
Subject: [PATCH 13/54] chore: prepare afgo for 1.8.0 release (#3207)
this change updates all AFGO dependencies to latest commit.
It also removes temporary Go1.17 out of memory temporary fix as 1.17.6 has this fixed now.
Signed-off-by: Baha Shaaban
---
cmd/aries-agent-mobile/check_unit.sh | 5 --
cmd/aries-agent-mobile/go.mod | 8 +--
cmd/aries-agent-mobile/go.sum | 8 +--
cmd/aries-agent-rest/go.mod | 10 +--
cmd/aries-agent-rest/go.sum | 9 ++-
cmd/aries-js-worker/go.mod | 10 +--
cmd/aries-js-worker/go.sum | 12 +---
component/storage/edv/go.mod | 11 ++--
component/storage/edv/go.sum | 18 ++++--
component/storage/indexeddb/go.mod | 34 ++++-------
component/storage/indexeddb/go.sum | 91 +++++++++++++++++++++-------
component/storage/leveldb/go.mod | 4 +-
component/storage/leveldb/go.sum | 10 +--
component/storageutil/go.mod | 4 +-
component/storageutil/go.sum | 10 +--
go.mod | 6 +-
go.sum | 12 ++--
scripts/check_go_integration.sh | 5 --
scripts/check_unit.sh | 5 --
scripts/check_unit_wasm.sh | 5 --
test/bdd/fixtures/agent-rest/.env | 2 +-
test/bdd/go.mod | 9 ++-
test/bdd/go.sum | 2 +-
test/component/go.mod | 8 ++-
test/component/go.sum | 4 +-
25 files changed, 166 insertions(+), 136 deletions(-)
diff --git a/cmd/aries-agent-mobile/check_unit.sh b/cmd/aries-agent-mobile/check_unit.sh
index 0200288be..d5af967b3 100755
--- a/cmd/aries-agent-mobile/check_unit.sh
+++ b/cmd/aries-agent-mobile/check_unit.sh
@@ -6,11 +6,6 @@
#
set -e
-# TODO: MacOS Monterey Golang fix, remove "MallocNanoZone=0" once https://github.com/golang/go/issues/49138 is resolved.
-# TODO: issue is now resolved in :https://github.com/golang/go/commit/5f6552018d1ec920c3ca3d459691528f48363c3c,
-# TODO" but will need to wait for next Go release.
-export MallocNanoZone=0
-
echo "Running $0"
GO_TEST_CMD="go test"
diff --git a/cmd/aries-agent-mobile/go.mod b/cmd/aries-agent-mobile/go.mod
index cd8597d9d..a549aa75b 100644
--- a/cmd/aries-agent-mobile/go.mod
+++ b/cmd/aries-agent-mobile/go.mod
@@ -9,9 +9,9 @@ go 1.17
require (
github.com/google/uuid v1.1.2
github.com/hyperledger/aries-framework-go v0.1.8-0.20220217153004-1622c70e5767
- github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220308060532-714cd5c18552
- github.com/hyperledger/aries-framework-go/spi v0.0.0-20220308060532-714cd5c18552
- github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220308060532-714cd5c18552
+ github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220322085443-50e8f9bd208b
+ github.com/hyperledger/aries-framework-go/spi v0.0.0-20220322085443-50e8f9bd208b
+ github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220322085443-50e8f9bd208b
github.com/piprate/json-gold v0.4.1-0.20210813112359-33b90c4ca86c
github.com/stretchr/testify v1.7.0
nhooyr.io/websocket v1.8.3
@@ -31,7 +31,7 @@ require (
github.com/golang/snappy v0.0.1 // indirect
github.com/google/tink/go v1.6.1-0.20210519071714-58be99b3c4d0 // indirect
github.com/gorilla/mux v1.7.3 // indirect
- github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220308060532-714cd5c18552 // indirect
+ github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220322085443-50e8f9bd208b // indirect
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a // indirect
github.com/kawamuray/jsonpath v0.0.0-20201211160320-7483bafabd7e // indirect
github.com/kilic/bls12-381 v0.1.1-0.20210503002446-7b7597926c69 // indirect
diff --git a/cmd/aries-agent-mobile/go.sum b/cmd/aries-agent-mobile/go.sum
index 2f312c07c..dab7b54f6 100644
--- a/cmd/aries-agent-mobile/go.sum
+++ b/cmd/aries-agent-mobile/go.sum
@@ -182,12 +182,12 @@ github.com/hashicorp/vault/sdk v0.1.13/go.mod h1:B+hVj7TpuQY1Y/GPbCpffmgd+tSEwvh
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
-github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220308060532-714cd5c18552 h1:5z5ACTvbjydtD9d04Inki7gy8k1RatVqi6zhSIIE0f8=
-github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220308060532-714cd5c18552/go.mod h1:eIac5lubCy3tw6D0sTluM5U6Bw3inBwUfjX17o2U7PE=
+github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220322085443-50e8f9bd208b h1:cZ1scj+jdCT6IYAXe/62CckfTXv1wr0vnFLh2biH2qQ=
+github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220322085443-50e8f9bd208b/go.mod h1:eIac5lubCy3tw6D0sTluM5U6Bw3inBwUfjX17o2U7PE=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210820153043-8b6f36d10ab9/go.mod h1:7jEZdg455syX4f+ozLgwhYfIuiEQ/TgdIoOyALMwPG0=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220217153004-1622c70e5767/go.mod h1:HojN6OAh8ZtXBe5X2arcSOe1SLo5Dsjqto8ICjSLQ2g=
-github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220308060532-714cd5c18552 h1:R9aDLtYSbbHUmLJhmTHdskmzHEBZiWnFy5pHjv5Ryhk=
-github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220308060532-714cd5c18552/go.mod h1:HojN6OAh8ZtXBe5X2arcSOe1SLo5Dsjqto8ICjSLQ2g=
+github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220322085443-50e8f9bd208b h1:tq8CYv5vCJBSG2CjWKNt4l1BzZVJUy+GGF4U80fJV8o=
+github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220322085443-50e8f9bd208b/go.mod h1:HojN6OAh8ZtXBe5X2arcSOe1SLo5Dsjqto8ICjSLQ2g=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
diff --git a/cmd/aries-agent-rest/go.mod b/cmd/aries-agent-rest/go.mod
index ac7894f44..f0e020a2f 100644
--- a/cmd/aries-agent-rest/go.mod
+++ b/cmd/aries-agent-rest/go.mod
@@ -9,10 +9,10 @@ go 1.17
require (
github.com/cenkalti/backoff/v4 v4.1.0
github.com/gorilla/mux v1.7.3
- github.com/hyperledger/aries-framework-go v0.1.8-0.20220217153004-1622c70e5767
- github.com/hyperledger/aries-framework-go/component/storage/leveldb v0.0.0-20220308060532-714cd5c18552
- github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220308060532-714cd5c18552
- github.com/hyperledger/aries-framework-go/spi v0.0.0-20220308060532-714cd5c18552
+ github.com/hyperledger/aries-framework-go v0.1.8-0.20220322085443-50e8f9bd208b
+ github.com/hyperledger/aries-framework-go/component/storage/leveldb v0.0.0-20220322085443-50e8f9bd208b
+ github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220322085443-50e8f9bd208b
+ github.com/hyperledger/aries-framework-go/spi v0.0.0-20220322085443-50e8f9bd208b
github.com/rs/cors v1.7.0
github.com/spf13/cobra v1.0.0
github.com/stretchr/testify v1.7.0
@@ -31,7 +31,7 @@ require (
github.com/golang/snappy v0.0.3 // indirect
github.com/google/tink/go v1.6.1-0.20210519071714-58be99b3c4d0 // indirect
github.com/google/uuid v1.1.2 // indirect
- github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220308060532-714cd5c18552 // indirect
+ github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220322085443-50e8f9bd208b // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a // indirect
github.com/kawamuray/jsonpath v0.0.0-20201211160320-7483bafabd7e // indirect
diff --git a/cmd/aries-agent-rest/go.sum b/cmd/aries-agent-rest/go.sum
index 4a2e1bfc3..a529e4bcd 100644
--- a/cmd/aries-agent-rest/go.sum
+++ b/cmd/aries-agent-rest/go.sum
@@ -214,12 +214,11 @@ github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKe
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
-github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220308060532-714cd5c18552 h1:5z5ACTvbjydtD9d04Inki7gy8k1RatVqi6zhSIIE0f8=
-github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220308060532-714cd5c18552/go.mod h1:eIac5lubCy3tw6D0sTluM5U6Bw3inBwUfjX17o2U7PE=
-github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210820153043-8b6f36d10ab9/go.mod h1:7jEZdg455syX4f+ozLgwhYfIuiEQ/TgdIoOyALMwPG0=
-github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210820175050-dcc7a225178d/go.mod h1:7jEZdg455syX4f+ozLgwhYfIuiEQ/TgdIoOyALMwPG0=
-github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220217153004-1622c70e5767 h1:XyfULUaaWSj+JRaILaxTUHFh0CujzODJ5P4qJNjZM+w=
+github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220322085443-50e8f9bd208b h1:cZ1scj+jdCT6IYAXe/62CckfTXv1wr0vnFLh2biH2qQ=
+github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220322085443-50e8f9bd208b/go.mod h1:eIac5lubCy3tw6D0sTluM5U6Bw3inBwUfjX17o2U7PE=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220217153004-1622c70e5767/go.mod h1:HojN6OAh8ZtXBe5X2arcSOe1SLo5Dsjqto8ICjSLQ2g=
+github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220322085443-50e8f9bd208b h1:tq8CYv5vCJBSG2CjWKNt4l1BzZVJUy+GGF4U80fJV8o=
+github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220322085443-50e8f9bd208b/go.mod h1:HojN6OAh8ZtXBe5X2arcSOe1SLo5Dsjqto8ICjSLQ2g=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
diff --git a/cmd/aries-js-worker/go.mod b/cmd/aries-js-worker/go.mod
index f7c697f20..061a28148 100644
--- a/cmd/aries-js-worker/go.mod
+++ b/cmd/aries-js-worker/go.mod
@@ -8,9 +8,9 @@ go 1.17
require (
github.com/google/uuid v1.1.2
- github.com/hyperledger/aries-framework-go v0.1.8-0.20220308060532-714cd5c18552
- github.com/hyperledger/aries-framework-go/component/storage/indexeddb v0.0.0-00010101000000-000000000000
- github.com/hyperledger/aries-framework-go/spi v0.0.0-20220308060532-714cd5c18552
+ github.com/hyperledger/aries-framework-go v0.1.8-0.20220322085443-50e8f9bd208b
+ github.com/hyperledger/aries-framework-go/component/storage/indexeddb v0.1.8-0.20220322085443-50e8f9bd208b
+ github.com/hyperledger/aries-framework-go/spi v0.0.0-20220322085443-50e8f9bd208b
github.com/mitchellh/mapstructure v1.3.0
github.com/stretchr/testify v1.7.0
)
@@ -29,8 +29,8 @@ require (
github.com/golang/snappy v0.0.1 // indirect
github.com/google/tink/go v1.6.1-0.20210519071714-58be99b3c4d0 // indirect
github.com/gorilla/mux v1.7.3 // indirect
- github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220308060532-714cd5c18552 // indirect
- github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220308060532-714cd5c18552 // indirect
+ github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220322085443-50e8f9bd208b // indirect
+ github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220322085443-50e8f9bd208b // indirect
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a // indirect
github.com/kawamuray/jsonpath v0.0.0-20201211160320-7483bafabd7e // indirect
github.com/kilic/bls12-381 v0.1.1-0.20210503002446-7b7597926c69 // indirect
diff --git a/cmd/aries-js-worker/go.sum b/cmd/aries-js-worker/go.sum
index 388776c01..95f53e3f4 100644
--- a/cmd/aries-js-worker/go.sum
+++ b/cmd/aries-js-worker/go.sum
@@ -55,7 +55,6 @@ github.com/btcsuite/btcd v0.22.0-beta h1:LTDpDKUM5EeOFBPM8IXpinEcmZ6FWfNZbE3lfrf
github.com/btcsuite/btcd v0.22.0-beta/go.mod h1:9n5ntfhhHQBIhUvlhDvD3Qg6fRUj4jkN0VB8L8svzOA=
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
-github.com/btcsuite/btcutil v1.0.1/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts=
github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce h1:YtWJF7RHm2pYCvA5t0RPmAaLUhREsKuKd+SLhxFbFeQ=
github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o=
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg=
@@ -183,10 +182,8 @@ github.com/hashicorp/vault/sdk v0.1.13/go.mod h1:B+hVj7TpuQY1Y/GPbCpffmgd+tSEwvh
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
-github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210820153043-8b6f36d10ab9/go.mod h1:7jEZdg455syX4f+ozLgwhYfIuiEQ/TgdIoOyALMwPG0=
-github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210820175050-dcc7a225178d/go.mod h1:7jEZdg455syX4f+ozLgwhYfIuiEQ/TgdIoOyALMwPG0=
-github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220217153004-1622c70e5767 h1:XyfULUaaWSj+JRaILaxTUHFh0CujzODJ5P4qJNjZM+w=
-github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220217153004-1622c70e5767/go.mod h1:HojN6OAh8ZtXBe5X2arcSOe1SLo5Dsjqto8ICjSLQ2g=
+github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220322085443-50e8f9bd208b h1:tq8CYv5vCJBSG2CjWKNt4l1BzZVJUy+GGF4U80fJV8o=
+github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220322085443-50e8f9bd208b/go.mod h1:HojN6OAh8ZtXBe5X2arcSOe1SLo5Dsjqto8ICjSLQ2g=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
@@ -199,7 +196,6 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/kawamuray/jsonpath v0.0.0-20201211160320-7483bafabd7e h1:Eh/0JuXDdcBHc39j4tFXKTy/AKiK7IQkGJXQxyryXiU=
github.com/kawamuray/jsonpath v0.0.0-20201211160320-7483bafabd7e/go.mod h1:dz00yqWNWlKa9ff7RJzpnHPAPUazsid3yhVzXcsok94=
-github.com/kilic/bls12-381 v0.0.0-20201104083100-a288617c07f1/go.mod h1:gcwDl9YLyNc3H3wmPXamu+8evD8TYUa6BjTsWnvdn7A=
github.com/kilic/bls12-381 v0.1.1-0.20210503002446-7b7597926c69 h1:kMJlf8z8wUcpyI+FQJIdGjAhfTww1y0AbQEv86bpVQI=
github.com/kilic/bls12-381 v0.1.1-0.20210503002446-7b7597926c69/go.mod h1:tlkavyke+Ac7h8R3gZIjI5LKBcvMlSWnXNMgT3vZXo8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
@@ -246,7 +242,6 @@ github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
-github.com/piprate/json-gold v0.4.0/go.mod h1:OK1z7UgtBZk06n2cDE2OSq1kffmjFFp5/2yhLLCz9UM=
github.com/piprate/json-gold v0.4.1-0.20210813112359-33b90c4ca86c h1:F4YQvOA7UTccz06y59KLw4C0iXD28hnKUP9R9zeSe8U=
github.com/piprate/json-gold v0.4.1-0.20210813112359-33b90c4ca86c/go.mod h1:OK1z7UgtBZk06n2cDE2OSq1kffmjFFp5/2yhLLCz9UM=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@@ -273,7 +268,6 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/teserakt-io/golang-ed25519 v0.0.0-20200315192543-8255be791ce4/go.mod h1:9PdLyPiZIiW3UopXyRnPYyjUXSpiQNHRLu8fOsR3o8M=
github.com/teserakt-io/golang-ed25519 v0.0.0-20210104091850-3888c087a4c8 h1:RBkacARv7qY5laaXGlF4wFB/tk5rnthhPb8oIBGoagY=
github.com/teserakt-io/golang-ed25519 v0.0.0-20210104091850-3888c087a4c8/go.mod h1:9PdLyPiZIiW3UopXyRnPYyjUXSpiQNHRLu8fOsR3o8M=
github.com/tidwall/gjson v1.6.7 h1:Mb1M9HZCRWEcXQ8ieJo7auYyyiSux6w9XN3AdTpxJrE=
@@ -402,7 +396,6 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191025090151-53bf42e6b339/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -421,7 +414,6 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20201211090839-8ad439b19e0f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=
diff --git a/component/storage/edv/go.mod b/component/storage/edv/go.mod
index d69aa1be9..1a1dc38b8 100644
--- a/component/storage/edv/go.mod
+++ b/component/storage/edv/go.mod
@@ -11,10 +11,10 @@ require (
github.com/cenkalti/backoff/v4 v4.0.2
github.com/google/tink/go v1.6.1-0.20210519071714-58be99b3c4d0
github.com/google/uuid v1.1.2
- github.com/hyperledger/aries-framework-go v0.1.8-0.20220217153004-1622c70e5767
- github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220217153004-1622c70e5767
- github.com/hyperledger/aries-framework-go/spi v0.0.0-20220217153004-1622c70e5767
- github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220217153004-1622c70e5767
+ github.com/hyperledger/aries-framework-go v0.1.8-0.20220322085443-50e8f9bd208b
+ github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220322085443-50e8f9bd208b
+ github.com/hyperledger/aries-framework-go/spi v0.0.0-20220322085443-50e8f9bd208b
+ github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220322085443-50e8f9bd208b
github.com/stretchr/testify v1.7.0
)
@@ -23,6 +23,9 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/kilic/bls12-381 v0.1.1-0.20210503002446-7b7597926c69 // indirect
+ github.com/mr-tron/base58 v1.1.3 // indirect
+ github.com/multiformats/go-base32 v0.0.3 // indirect
+ github.com/multiformats/go-multibase v0.0.1 // indirect
github.com/piprate/json-gold v0.4.1-0.20210813112359-33b90c4ca86c // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect
diff --git a/component/storage/edv/go.sum b/component/storage/edv/go.sum
index c48b4c89a..12b80c621 100644
--- a/component/storage/edv/go.sum
+++ b/component/storage/edv/go.sum
@@ -175,17 +175,21 @@ github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKe
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/hyperledger/aries-framework-go v0.1.7-0.20210421203733-b5dfd703a8fc/go.mod h1:tBgxVOKcNero3QI21iNf3oxxHkgRMDOby937cqHEvW4=
github.com/hyperledger/aries-framework-go v0.1.7-0.20210603210127-e57b8c94e3cf/go.mod h1:h6L+YoXtw90OZrH2IequxukIGwzfSpz8pUueQ9T5KqI=
-github.com/hyperledger/aries-framework-go v0.1.8-0.20220217153004-1622c70e5767 h1:F/yxXrzPB1T2nawE4u3Wcu3gHVcNbTY/aUV8kqfk8r4=
github.com/hyperledger/aries-framework-go v0.1.8-0.20220217153004-1622c70e5767/go.mod h1:rBMOJVwyHyYbOqbb3IB/ExBkHyvFLht/W81s24GmjcE=
+github.com/hyperledger/aries-framework-go v0.1.8-0.20220322085443-50e8f9bd208b h1:q+Plvnq7/n3IwTO6IOhBXn//txifpeo/OErvM1ivh8s=
+github.com/hyperledger/aries-framework-go v0.1.8-0.20220322085443-50e8f9bd208b/go.mod h1:bqeLa1s8fQ7YueGOOk0Q+r48FGF7sd8GEaS/CyEo/iY=
github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20210520055214-ae429bb89bf7/go.mod h1:7D+Y5J9cIsUrMGFAsIED+3bAPNjxp6ggXo0/kT5N6BI=
github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20210820175050-dcc7a225178d/go.mod h1:i40JkMHCh9cHHxSc1SYznO3xDH6ly5CE0B3vPYZVeWI=
+github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220308060532-714cd5c18552/go.mod h1:eIac5lubCy3tw6D0sTluM5U6Bw3inBwUfjX17o2U7PE=
github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20210409151411-eeeb8508bd87/go.mod h1:kJT7bcaKsvk1lMp2jqS8srF+ZUie2H4MoPbL2V29dgA=
github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20210421203733-b5dfd703a8fc/go.mod h1:uGc7F3tXQIY6xjs8VEI6/oxp4ZDXDfGjPMCTgax5Zhc=
github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20210520055214-ae429bb89bf7/go.mod h1:aP6VnxeSbmD1OcV2f8y0dRV9fkIZp/+mzmgKxxmSJG4=
github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20210807121559-b41545a4f1e8/go.mod h1:k8CjDLBLxygTEj3D077OeH4SJsVE3mK60AyeO/C9sxs=
github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20210820175050-dcc7a225178d/go.mod h1:wdgGPwXzih+QD2Q4nvMnGO0dm0D0rxmzQcSNLcW6fcg=
-github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220217153004-1622c70e5767 h1:BX1LZzhs9ONfxMPSPQPhXuXQllJSYO7DjrQ0w2uxJHo=
github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220217153004-1622c70e5767/go.mod h1:yLgRpVlZ2heeeOpTgvEnG/yHL9q1keUu5ILQ6s2qpLU=
+github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220308060532-714cd5c18552/go.mod h1:yLgRpVlZ2heeeOpTgvEnG/yHL9q1keUu5ILQ6s2qpLU=
+github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220322085443-50e8f9bd208b h1:IoD7+sHQRLMouwHjhrOj5vhg+rPt/aKl4P+WiBZVHVk=
+github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220322085443-50e8f9bd208b/go.mod h1:yLgRpVlZ2heeeOpTgvEnG/yHL9q1keUu5ILQ6s2qpLU=
github.com/hyperledger/aries-framework-go/spi v0.0.0-20210320144851-40976de98ccf/go.mod h1:fDr9wW00GJJl1lR1SFHmJW8utIocdvjO5RNhAYS05EY=
github.com/hyperledger/aries-framework-go/spi v0.0.0-20210322152545-e6ebe2c79a2a/go.mod h1:fDr9wW00GJJl1lR1SFHmJW8utIocdvjO5RNhAYS05EY=
github.com/hyperledger/aries-framework-go/spi v0.0.0-20210409151411-eeeb8508bd87/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
@@ -201,16 +205,19 @@ github.com/hyperledger/aries-framework-go/spi v0.0.0-20210818133831-4e22573c126d
github.com/hyperledger/aries-framework-go/spi v0.0.0-20210820153043-8b6f36d10ab9/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
github.com/hyperledger/aries-framework-go/spi v0.0.0-20210820175050-dcc7a225178d/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
github.com/hyperledger/aries-framework-go/spi v0.0.0-20211203210130-e927c9ed581a/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
-github.com/hyperledger/aries-framework-go/spi v0.0.0-20220217153004-1622c70e5767 h1:sgn8Oplz12s0YMheYRXYedeBW9lJXh8/MUdWCrADx0c=
github.com/hyperledger/aries-framework-go/spi v0.0.0-20220217153004-1622c70e5767/go.mod h1:4bD5c5fj5K7rkQurVa/8I8+TfNcI4bxIBzaUNcxTOTg=
+github.com/hyperledger/aries-framework-go/spi v0.0.0-20220308060532-714cd5c18552/go.mod h1:4bD5c5fj5K7rkQurVa/8I8+TfNcI4bxIBzaUNcxTOTg=
+github.com/hyperledger/aries-framework-go/spi v0.0.0-20220322085443-50e8f9bd208b h1:Fo9mK3eB+TiYu2/hbTWtt0kWg9j1QRqnnbQQqaytJzE=
+github.com/hyperledger/aries-framework-go/spi v0.0.0-20220322085443-50e8f9bd208b/go.mod h1:4bD5c5fj5K7rkQurVa/8I8+TfNcI4bxIBzaUNcxTOTg=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210324232048-34ff560ed041/go.mod h1:eKGEEe+PJNDQo7kVif3sUKBWwnsQDkE3gD/QlpmukcQ=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210409151411-eeeb8508bd87/go.mod h1:JHzDtgJLd0134iLFXLxGBjJF+Z+TgiElA/5oVgMazts=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210421203733-b5dfd703a8fc/go.mod h1:asiCVCtH/nocWKhZRMz12aFgdUh8lRHqKis0M8Ei/4I=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210603182844-353ecb34cf4d/go.mod h1:J0SlvlnETEdYojUW4om/UINH0Uobmbtw46cH4DGXv5g=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210807121559-b41545a4f1e8/go.mod h1:3idbNcBl2wdRaETayzpY95KK5SfSzwXb5uqLW/Ldh0g=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210820153043-8b6f36d10ab9/go.mod h1:7jEZdg455syX4f+ozLgwhYfIuiEQ/TgdIoOyALMwPG0=
-github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220217153004-1622c70e5767 h1:XyfULUaaWSj+JRaILaxTUHFh0CujzODJ5P4qJNjZM+w=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220217153004-1622c70e5767/go.mod h1:HojN6OAh8ZtXBe5X2arcSOe1SLo5Dsjqto8ICjSLQ2g=
+github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220322085443-50e8f9bd208b h1:tq8CYv5vCJBSG2CjWKNt4l1BzZVJUy+GGF4U80fJV8o=
+github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220322085443-50e8f9bd208b/go.mod h1:HojN6OAh8ZtXBe5X2arcSOe1SLo5Dsjqto8ICjSLQ2g=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
@@ -247,8 +254,11 @@ github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQz
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8=
+github.com/mr-tron/base58 v1.1.3 h1:v+sk57XuaCKGXpWtVBX8YJzO7hMGx4Aajh4TQbdEFdc=
github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
+github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI=
github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA=
+github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA=
github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs=
github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc=
github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE=
diff --git a/component/storage/indexeddb/go.mod b/component/storage/indexeddb/go.mod
index 4432c895a..fe11f9e35 100644
--- a/component/storage/indexeddb/go.mod
+++ b/component/storage/indexeddb/go.mod
@@ -8,28 +8,24 @@ go 1.17
require (
github.com/google/uuid v1.1.2
- github.com/hyperledger/aries-framework-go v0.1.7-0.20210409151411-eeeb8508bd87
- github.com/hyperledger/aries-framework-go/spi v0.0.0-20210820175050-dcc7a225178d
- github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210820175050-dcc7a225178d
+ github.com/hyperledger/aries-framework-go v0.1.8-0.20220322085443-50e8f9bd208b
+ github.com/hyperledger/aries-framework-go/spi v0.0.0-20220322085443-50e8f9bd208b
+ github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220322085443-50e8f9bd208b
github.com/stretchr/testify v1.7.0
)
require (
- github.com/PaesslerAG/gval v1.1.0 // indirect
- github.com/PaesslerAG/jsonpath v0.1.1 // indirect
github.com/VictoriaMetrics/fastcache v1.5.7 // indirect
- github.com/btcsuite/btcd v0.20.1-beta // indirect
- github.com/btcsuite/btcutil v1.0.1 // indirect
+ github.com/btcsuite/btcd v0.22.0-beta // indirect
+ github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce // indirect
github.com/cenkalti/backoff/v4 v4.0.2 // indirect
github.com/cespare/xxhash/v2 v2.1.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
- github.com/golang/protobuf v1.5.0 // indirect
+ github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/snappy v0.0.1 // indirect
github.com/google/tink/go v1.6.1-0.20210519071714-58be99b3c4d0 // indirect
- github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20210603182844-353ecb34cf4d // indirect
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a // indirect
- github.com/kawamuray/jsonpath v0.0.0-20201211160320-7483bafabd7e // indirect
- github.com/kilic/bls12-381 v0.0.0-20201104083100-a288617c07f1 // indirect
+ github.com/kilic/bls12-381 v0.1.1-0.20210503002446-7b7597926c69 // indirect
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 // indirect
github.com/minio/sha256-simd v0.1.1 // indirect
github.com/mitchellh/mapstructure v1.1.2 // indirect
@@ -38,22 +34,18 @@ require (
github.com/multiformats/go-multibase v0.0.1 // indirect
github.com/multiformats/go-multihash v0.0.13 // indirect
github.com/multiformats/go-varint v0.0.5 // indirect
- github.com/piprate/json-gold v0.4.0 // indirect
+ github.com/piprate/json-gold v0.4.1-0.20210813112359-33b90c4ca86c // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/square/go-jose/v3 v3.0.0-20200630053402-0a67ce9b0693 // indirect
- github.com/teserakt-io/golang-ed25519 v0.0.0-20200315192543-8255be791ce4 // indirect
- github.com/tidwall/gjson v1.6.7 // indirect
- github.com/tidwall/match v1.0.3 // indirect
- github.com/tidwall/pretty v1.0.2 // indirect
- github.com/tidwall/sjson v1.1.4 // indirect
+ github.com/teserakt-io/golang-ed25519 v0.0.0-20210104091850-3888c087a4c8 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
- golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0 // indirect
- golang.org/x/sys v0.0.0-20201211090839-8ad439b19e0f // indirect
- google.golang.org/protobuf v1.26.0 // indirect
- gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
+ golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e // indirect
+ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect
+ google.golang.org/protobuf v1.27.1 // indirect
+ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
)
diff --git a/component/storage/indexeddb/go.sum b/component/storage/indexeddb/go.sum
index 0449a8a6e..cf722c880 100644
--- a/component/storage/indexeddb/go.sum
+++ b/component/storage/indexeddb/go.sum
@@ -51,15 +51,19 @@ github.com/aws/aws-sdk-go v1.36.29/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2z
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bluele/gcache v0.0.0-20190518031135-bc40bd653833 h1:yCfXxYaelOyqnia8F/Yng47qhmfC9nKTRIbYRrRueq4=
github.com/bluele/gcache v0.0.0-20190518031135-bc40bd653833/go.mod h1:8c4/i2VlovMO2gBnHGQPN5EJw+H0lx1u/5p+cgsXtCk=
-github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw=
github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
+github.com/btcsuite/btcd v0.22.0-beta h1:LTDpDKUM5EeOFBPM8IXpinEcmZ6FWfNZbE3lfrfdnWo=
+github.com/btcsuite/btcd v0.22.0-beta/go.mod h1:9n5ntfhhHQBIhUvlhDvD3Qg6fRUj4jkN0VB8L8svzOA=
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
-github.com/btcsuite/btcutil v1.0.1 h1:GKOz8BnRjYrb/JTKgaOk+zh26NWNdSNvdvv0xoAZMSA=
github.com/btcsuite/btcutil v1.0.1/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts=
+github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce h1:YtWJF7RHm2pYCvA5t0RPmAaLUhREsKuKd+SLhxFbFeQ=
+github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o=
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg=
github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY=
+github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I=
github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
+github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY=
github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
github.com/cenkalti/backoff/v4 v4.0.2 h1:JIufpQLbh4DkbQoii76ItQIUFzevQSqOLZca4eamEDs=
@@ -76,6 +80,7 @@ github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
@@ -117,8 +122,9 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
-github.com/golang/protobuf v1.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
+github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
+github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
@@ -174,25 +180,53 @@ github.com/hashicorp/vault/sdk v0.1.13/go.mod h1:B+hVj7TpuQY1Y/GPbCpffmgd+tSEwvh
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
-github.com/hyperledger/aries-framework-go v0.1.7-0.20210409151411-eeeb8508bd87 h1:2g7LCxtCYmOI6yHjpU8hA5AEWnp+/HeA8+GVLgr/D1k=
-github.com/hyperledger/aries-framework-go v0.1.7-0.20210409151411-eeeb8508bd87/go.mod h1:9Mz/wkgyzXKxuOZObASCWRprt30P+xSsL08T8VBFRnk=
-github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20210320144851-40976de98ccf/go.mod h1:HVV8sifdHIyLkrlgmK/6+3YWKnOJPUfoNU+4SwQqMSs=
-github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20210603182844-353ecb34cf4d h1:6Zc8CSLZfeVzuKX59pTWZPFN4c/jgjdrRcVq7QQuAd8=
-github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20210603182844-353ecb34cf4d/go.mod h1:aP6VnxeSbmD1OcV2f8y0dRV9fkIZp/+mzmgKxxmSJG4=
-github.com/hyperledger/aries-framework-go/spi v0.0.0-20210310001230-bc1bd8ea889c/go.mod h1:fDr9wW00GJJl1lR1SFHmJW8utIocdvjO5RNhAYS05EY=
-github.com/hyperledger/aries-framework-go/spi v0.0.0-20210310160016-d5eea2ecdd50/go.mod h1:fDr9wW00GJJl1lR1SFHmJW8utIocdvjO5RNhAYS05EY=
+github.com/hyperledger/aries-framework-go v0.1.7-0.20210421203733-b5dfd703a8fc/go.mod h1:tBgxVOKcNero3QI21iNf3oxxHkgRMDOby937cqHEvW4=
+github.com/hyperledger/aries-framework-go v0.1.7-0.20210603210127-e57b8c94e3cf/go.mod h1:h6L+YoXtw90OZrH2IequxukIGwzfSpz8pUueQ9T5KqI=
+github.com/hyperledger/aries-framework-go v0.1.8-0.20220217153004-1622c70e5767/go.mod h1:rBMOJVwyHyYbOqbb3IB/ExBkHyvFLht/W81s24GmjcE=
+github.com/hyperledger/aries-framework-go v0.1.8-0.20220322085443-50e8f9bd208b h1:q+Plvnq7/n3IwTO6IOhBXn//txifpeo/OErvM1ivh8s=
+github.com/hyperledger/aries-framework-go v0.1.8-0.20220322085443-50e8f9bd208b/go.mod h1:bqeLa1s8fQ7YueGOOk0Q+r48FGF7sd8GEaS/CyEo/iY=
+github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20210520055214-ae429bb89bf7/go.mod h1:7D+Y5J9cIsUrMGFAsIED+3bAPNjxp6ggXo0/kT5N6BI=
+github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20210820175050-dcc7a225178d/go.mod h1:i40JkMHCh9cHHxSc1SYznO3xDH6ly5CE0B3vPYZVeWI=
+github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220308060532-714cd5c18552/go.mod h1:eIac5lubCy3tw6D0sTluM5U6Bw3inBwUfjX17o2U7PE=
+github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20210409151411-eeeb8508bd87/go.mod h1:kJT7bcaKsvk1lMp2jqS8srF+ZUie2H4MoPbL2V29dgA=
+github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20210421203733-b5dfd703a8fc/go.mod h1:uGc7F3tXQIY6xjs8VEI6/oxp4ZDXDfGjPMCTgax5Zhc=
+github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20210520055214-ae429bb89bf7/go.mod h1:aP6VnxeSbmD1OcV2f8y0dRV9fkIZp/+mzmgKxxmSJG4=
+github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20210807121559-b41545a4f1e8/go.mod h1:k8CjDLBLxygTEj3D077OeH4SJsVE3mK60AyeO/C9sxs=
+github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20210820175050-dcc7a225178d/go.mod h1:wdgGPwXzih+QD2Q4nvMnGO0dm0D0rxmzQcSNLcW6fcg=
+github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220217153004-1622c70e5767/go.mod h1:yLgRpVlZ2heeeOpTgvEnG/yHL9q1keUu5ILQ6s2qpLU=
+github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220308060532-714cd5c18552 h1:5YpK44u/Ou4FTdzRvQy3iZiNE5W2E91j7OK/65V+Nv0=
+github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220308060532-714cd5c18552/go.mod h1:yLgRpVlZ2heeeOpTgvEnG/yHL9q1keUu5ILQ6s2qpLU=
github.com/hyperledger/aries-framework-go/spi v0.0.0-20210320144851-40976de98ccf/go.mod h1:fDr9wW00GJJl1lR1SFHmJW8utIocdvjO5RNhAYS05EY=
+github.com/hyperledger/aries-framework-go/spi v0.0.0-20210322152545-e6ebe2c79a2a/go.mod h1:fDr9wW00GJJl1lR1SFHmJW8utIocdvjO5RNhAYS05EY=
+github.com/hyperledger/aries-framework-go/spi v0.0.0-20210409151411-eeeb8508bd87/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
+github.com/hyperledger/aries-framework-go/spi v0.0.0-20210412201938-efffe3eafcd1/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
github.com/hyperledger/aries-framework-go/spi v0.0.0-20210421165342-de8f911415e3/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
github.com/hyperledger/aries-framework-go/spi v0.0.0-20210421203733-b5dfd703a8fc/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
+github.com/hyperledger/aries-framework-go/spi v0.0.0-20210520055214-ae429bb89bf7/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
+github.com/hyperledger/aries-framework-go/spi v0.0.0-20210603134946-53276bbf0c28/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
+github.com/hyperledger/aries-framework-go/spi v0.0.0-20210603182844-353ecb34cf4d/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
+github.com/hyperledger/aries-framework-go/spi v0.0.0-20210806210220-65863dbe349a/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
+github.com/hyperledger/aries-framework-go/spi v0.0.0-20210807121559-b41545a4f1e8/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
github.com/hyperledger/aries-framework-go/spi v0.0.0-20210818133831-4e22573c126d/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
-github.com/hyperledger/aries-framework-go/spi v0.0.0-20210820175050-dcc7a225178d h1:0JfPT4ORTdFMQknng3TiA2G/YY80+AMmty/47K7z4Rw=
+github.com/hyperledger/aries-framework-go/spi v0.0.0-20210820153043-8b6f36d10ab9/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
github.com/hyperledger/aries-framework-go/spi v0.0.0-20210820175050-dcc7a225178d/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
-github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210310160016-d5eea2ecdd50/go.mod h1:AybsT4/saiuxdVhK5CgOLIkcNMPZtX3GAUMOjHcLLjk=
+github.com/hyperledger/aries-framework-go/spi v0.0.0-20211203210130-e927c9ed581a/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
+github.com/hyperledger/aries-framework-go/spi v0.0.0-20220217153004-1622c70e5767/go.mod h1:4bD5c5fj5K7rkQurVa/8I8+TfNcI4bxIBzaUNcxTOTg=
+github.com/hyperledger/aries-framework-go/spi v0.0.0-20220308060532-714cd5c18552/go.mod h1:4bD5c5fj5K7rkQurVa/8I8+TfNcI4bxIBzaUNcxTOTg=
+github.com/hyperledger/aries-framework-go/spi v0.0.0-20220322085443-50e8f9bd208b h1:Fo9mK3eB+TiYu2/hbTWtt0kWg9j1QRqnnbQQqaytJzE=
+github.com/hyperledger/aries-framework-go/spi v0.0.0-20220322085443-50e8f9bd208b/go.mod h1:4bD5c5fj5K7rkQurVa/8I8+TfNcI4bxIBzaUNcxTOTg=
+github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210324232048-34ff560ed041/go.mod h1:eKGEEe+PJNDQo7kVif3sUKBWwnsQDkE3gD/QlpmukcQ=
+github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210409151411-eeeb8508bd87/go.mod h1:JHzDtgJLd0134iLFXLxGBjJF+Z+TgiElA/5oVgMazts=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210421203733-b5dfd703a8fc/go.mod h1:asiCVCtH/nocWKhZRMz12aFgdUh8lRHqKis0M8Ei/4I=
-github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210820175050-dcc7a225178d h1:6n55F8lsCR2OGGZ+3RB2ppXkdmtVaoTV7MoTvpFRyTg=
-github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210820175050-dcc7a225178d/go.mod h1:7jEZdg455syX4f+ozLgwhYfIuiEQ/TgdIoOyALMwPG0=
+github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210603182844-353ecb34cf4d/go.mod h1:J0SlvlnETEdYojUW4om/UINH0Uobmbtw46cH4DGXv5g=
+github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210807121559-b41545a4f1e8/go.mod h1:3idbNcBl2wdRaETayzpY95KK5SfSzwXb5uqLW/Ldh0g=
+github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210820153043-8b6f36d10ab9/go.mod h1:7jEZdg455syX4f+ozLgwhYfIuiEQ/TgdIoOyALMwPG0=
+github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220217153004-1622c70e5767/go.mod h1:HojN6OAh8ZtXBe5X2arcSOe1SLo5Dsjqto8ICjSLQ2g=
+github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220322085443-50e8f9bd208b h1:tq8CYv5vCJBSG2CjWKNt4l1BzZVJUy+GGF4U80fJV8o=
+github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220322085443-50e8f9bd208b/go.mod h1:HojN6OAh8ZtXBe5X2arcSOe1SLo5Dsjqto8ICjSLQ2g=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
+github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a h1:zPPuIq2jAWWPTrGt70eK/BSch+gFAGrNzecsoENgu2o=
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a/go.mod h1:yL958EeXv8Ylng6IfnvG4oflryUi3vgA3xPs9hmII1s=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
@@ -202,8 +236,9 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/kawamuray/jsonpath v0.0.0-20201211160320-7483bafabd7e h1:Eh/0JuXDdcBHc39j4tFXKTy/AKiK7IQkGJXQxyryXiU=
github.com/kawamuray/jsonpath v0.0.0-20201211160320-7483bafabd7e/go.mod h1:dz00yqWNWlKa9ff7RJzpnHPAPUazsid3yhVzXcsok94=
-github.com/kilic/bls12-381 v0.0.0-20201104083100-a288617c07f1 h1:fLyvBx6b/VrqcC1KlgTsPdpX3BcwGRWV8P6QfdgOLuw=
github.com/kilic/bls12-381 v0.0.0-20201104083100-a288617c07f1/go.mod h1:gcwDl9YLyNc3H3wmPXamu+8evD8TYUa6BjTsWnvdn7A=
+github.com/kilic/bls12-381 v0.1.1-0.20210503002446-7b7597926c69 h1:kMJlf8z8wUcpyI+FQJIdGjAhfTww1y0AbQEv86bpVQI=
+github.com/kilic/bls12-381 v0.1.1-0.20210503002446-7b7597926c69/go.mod h1:tlkavyke+Ac7h8R3gZIjI5LKBcvMlSWnXNMgT3vZXo8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
github.com/klauspost/compress v1.10.0/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
@@ -242,11 +277,13 @@ github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXS
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
-github.com/piprate/json-gold v0.4.0 h1:XQ6ZMLCjuXhtvqr60IrGl2uNYojl64B/dIUmI2iqThs=
github.com/piprate/json-gold v0.4.0/go.mod h1:OK1z7UgtBZk06n2cDE2OSq1kffmjFFp5/2yhLLCz9UM=
+github.com/piprate/json-gold v0.4.1-0.20210813112359-33b90c4ca86c h1:F4YQvOA7UTccz06y59KLw4C0iXD28hnKUP9R9zeSe8U=
+github.com/piprate/json-gold v0.4.1-0.20210813112359-33b90c4ca86c/go.mod h1:OK1z7UgtBZk06n2cDE2OSq1kffmjFFp5/2yhLLCz9UM=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@@ -271,8 +308,9 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/teserakt-io/golang-ed25519 v0.0.0-20200315192543-8255be791ce4 h1:Sq/68UWgBzKT+pLTUTkSf0jS2IUwwXLFlZmeh+nAzQM=
github.com/teserakt-io/golang-ed25519 v0.0.0-20200315192543-8255be791ce4/go.mod h1:9PdLyPiZIiW3UopXyRnPYyjUXSpiQNHRLu8fOsR3o8M=
+github.com/teserakt-io/golang-ed25519 v0.0.0-20210104091850-3888c087a4c8 h1:RBkacARv7qY5laaXGlF4wFB/tk5rnthhPb8oIBGoagY=
+github.com/teserakt-io/golang-ed25519 v0.0.0-20210104091850-3888c087a4c8/go.mod h1:9PdLyPiZIiW3UopXyRnPYyjUXSpiQNHRLu8fOsR3o8M=
github.com/tidwall/gjson v1.6.7 h1:Mb1M9HZCRWEcXQ8ieJo7auYyyiSux6w9XN3AdTpxJrE=
github.com/tidwall/gjson v1.6.7/go.mod h1:zeFuBCIqD4sN/gmqBzZ4j7Jd6UcA2Fc56x7QFsv+8fI=
github.com/tidwall/match v1.0.3 h1:FQUVvBImDutD8wJLN6c5eMzWtjgONK9MwIBCOrUJKeE=
@@ -306,9 +344,11 @@ golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0 h1:hb9wdF1z5waM+dSIICn1l0DkLVDT3hqhhQsDNUmHPRE=
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e h1:gsTQYXdTw2Gq7RBsWvlQ91b+aEQ6bXFUngBGuR8sPpI=
+golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -339,6 +379,7 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -367,6 +408,7 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -413,8 +455,13 @@ golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20201211090839-8ad439b19e0f h1:QdHQnPce6K4XQewki9WNbG5KOROuDzqO3NaYjI1cXJ0=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201211090839-8ad439b19e0f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=
+golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -550,8 +597,9 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
-google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
+google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
+google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
@@ -563,8 +611,9 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
+gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
diff --git a/component/storage/leveldb/go.mod b/component/storage/leveldb/go.mod
index 6fd974669..f2e2526d2 100644
--- a/component/storage/leveldb/go.mod
+++ b/component/storage/leveldb/go.mod
@@ -8,8 +8,8 @@ go 1.17
require (
github.com/google/uuid v1.1.2
- github.com/hyperledger/aries-framework-go/spi v0.0.0-20210820175050-dcc7a225178d
- github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210820175050-dcc7a225178d
+ github.com/hyperledger/aries-framework-go/spi v0.0.0-20220322085443-50e8f9bd208b
+ github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220322085443-50e8f9bd208b
github.com/stretchr/testify v1.7.0
github.com/syndtr/goleveldb v1.0.0
)
diff --git a/component/storage/leveldb/go.sum b/component/storage/leveldb/go.sum
index f562782c7..0dfc95c77 100644
--- a/component/storage/leveldb/go.sum
+++ b/component/storage/leveldb/go.sum
@@ -10,11 +10,11 @@ github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
-github.com/hyperledger/aries-framework-go/spi v0.0.0-20210818133831-4e22573c126d/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
-github.com/hyperledger/aries-framework-go/spi v0.0.0-20210820175050-dcc7a225178d h1:0JfPT4ORTdFMQknng3TiA2G/YY80+AMmty/47K7z4Rw=
-github.com/hyperledger/aries-framework-go/spi v0.0.0-20210820175050-dcc7a225178d/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
-github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210820175050-dcc7a225178d h1:6n55F8lsCR2OGGZ+3RB2ppXkdmtVaoTV7MoTvpFRyTg=
-github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210820175050-dcc7a225178d/go.mod h1:7jEZdg455syX4f+ozLgwhYfIuiEQ/TgdIoOyALMwPG0=
+github.com/hyperledger/aries-framework-go/spi v0.0.0-20211203210130-e927c9ed581a/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
+github.com/hyperledger/aries-framework-go/spi v0.0.0-20220322085443-50e8f9bd208b h1:Fo9mK3eB+TiYu2/hbTWtt0kWg9j1QRqnnbQQqaytJzE=
+github.com/hyperledger/aries-framework-go/spi v0.0.0-20220322085443-50e8f9bd208b/go.mod h1:4bD5c5fj5K7rkQurVa/8I8+TfNcI4bxIBzaUNcxTOTg=
+github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220322085443-50e8f9bd208b h1:tq8CYv5vCJBSG2CjWKNt4l1BzZVJUy+GGF4U80fJV8o=
+github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220322085443-50e8f9bd208b/go.mod h1:HojN6OAh8ZtXBe5X2arcSOe1SLo5Dsjqto8ICjSLQ2g=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
diff --git a/component/storageutil/go.mod b/component/storageutil/go.mod
index b837fc805..d617b7200 100644
--- a/component/storageutil/go.mod
+++ b/component/storageutil/go.mod
@@ -8,8 +8,8 @@ go 1.17
require (
github.com/google/uuid v1.1.2
- github.com/hyperledger/aries-framework-go/spi v0.0.0-20210820153043-8b6f36d10ab9
- github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210820153043-8b6f36d10ab9
+ github.com/hyperledger/aries-framework-go/spi v0.0.0-20220322085443-50e8f9bd208b
+ github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220322085443-50e8f9bd208b
github.com/stretchr/testify v1.7.0
)
diff --git a/component/storageutil/go.sum b/component/storageutil/go.sum
index a8440e150..cc7d3c6de 100644
--- a/component/storageutil/go.sum
+++ b/component/storageutil/go.sum
@@ -3,11 +3,11 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/hyperledger/aries-framework-go/spi v0.0.0-20210818133831-4e22573c126d/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
-github.com/hyperledger/aries-framework-go/spi v0.0.0-20210820153043-8b6f36d10ab9 h1:SqqCBXYIp/NeGTqh5MApxUuqfrPd2+f6tV+SJxptxek=
-github.com/hyperledger/aries-framework-go/spi v0.0.0-20210820153043-8b6f36d10ab9/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
-github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210820153043-8b6f36d10ab9 h1:LX6OckfTI2CHFFVSaqKoZR4G2JxczZfsvvqplmiwJwA=
-github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210820153043-8b6f36d10ab9/go.mod h1:7jEZdg455syX4f+ozLgwhYfIuiEQ/TgdIoOyALMwPG0=
+github.com/hyperledger/aries-framework-go/spi v0.0.0-20211203210130-e927c9ed581a/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
+github.com/hyperledger/aries-framework-go/spi v0.0.0-20220322085443-50e8f9bd208b h1:Fo9mK3eB+TiYu2/hbTWtt0kWg9j1QRqnnbQQqaytJzE=
+github.com/hyperledger/aries-framework-go/spi v0.0.0-20220322085443-50e8f9bd208b/go.mod h1:4bD5c5fj5K7rkQurVa/8I8+TfNcI4bxIBzaUNcxTOTg=
+github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220322085443-50e8f9bd208b h1:tq8CYv5vCJBSG2CjWKNt4l1BzZVJUy+GGF4U80fJV8o=
+github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220322085443-50e8f9bd208b/go.mod h1:HojN6OAh8ZtXBe5X2arcSOe1SLo5Dsjqto8ICjSLQ2g=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
diff --git a/go.mod b/go.mod
index 072c8ce35..e0f3fd491 100644
--- a/go.mod
+++ b/go.mod
@@ -17,9 +17,9 @@ require (
github.com/google/tink/go v1.6.1-0.20210519071714-58be99b3c4d0
github.com/google/uuid v1.1.2
github.com/gorilla/mux v1.7.3
- github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220308060532-714cd5c18552
- github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220308060532-714cd5c18552
- github.com/hyperledger/aries-framework-go/spi v0.0.0-20220308060532-714cd5c18552
+ github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220322085443-50e8f9bd208b
+ github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220322085443-50e8f9bd208b
+ github.com/hyperledger/aries-framework-go/spi v0.0.0-20220322085443-50e8f9bd208b
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a
github.com/kawamuray/jsonpath v0.0.0-20201211160320-7483bafabd7e
github.com/kilic/bls12-381 v0.1.1-0.20210503002446-7b7597926c69
diff --git a/go.sum b/go.sum
index 479dda2cb..7c03f50a2 100644
--- a/go.sum
+++ b/go.sum
@@ -190,16 +190,16 @@ github.com/hyperledger/aries-framework-go v0.1.7-0.20210603210127-e57b8c94e3cf/g
github.com/hyperledger/aries-framework-go v0.1.8-0.20220217153004-1622c70e5767/go.mod h1:rBMOJVwyHyYbOqbb3IB/ExBkHyvFLht/W81s24GmjcE=
github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20210520055214-ae429bb89bf7/go.mod h1:7D+Y5J9cIsUrMGFAsIED+3bAPNjxp6ggXo0/kT5N6BI=
github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20210820175050-dcc7a225178d/go.mod h1:i40JkMHCh9cHHxSc1SYznO3xDH6ly5CE0B3vPYZVeWI=
-github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220308060532-714cd5c18552 h1:5z5ACTvbjydtD9d04Inki7gy8k1RatVqi6zhSIIE0f8=
-github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220308060532-714cd5c18552/go.mod h1:eIac5lubCy3tw6D0sTluM5U6Bw3inBwUfjX17o2U7PE=
+github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220322085443-50e8f9bd208b h1:cZ1scj+jdCT6IYAXe/62CckfTXv1wr0vnFLh2biH2qQ=
+github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220322085443-50e8f9bd208b/go.mod h1:eIac5lubCy3tw6D0sTluM5U6Bw3inBwUfjX17o2U7PE=
github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20210409151411-eeeb8508bd87/go.mod h1:kJT7bcaKsvk1lMp2jqS8srF+ZUie2H4MoPbL2V29dgA=
github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20210421203733-b5dfd703a8fc/go.mod h1:uGc7F3tXQIY6xjs8VEI6/oxp4ZDXDfGjPMCTgax5Zhc=
github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20210520055214-ae429bb89bf7/go.mod h1:aP6VnxeSbmD1OcV2f8y0dRV9fkIZp/+mzmgKxxmSJG4=
github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20210807121559-b41545a4f1e8/go.mod h1:k8CjDLBLxygTEj3D077OeH4SJsVE3mK60AyeO/C9sxs=
github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20210820175050-dcc7a225178d/go.mod h1:wdgGPwXzih+QD2Q4nvMnGO0dm0D0rxmzQcSNLcW6fcg=
github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220217153004-1622c70e5767/go.mod h1:yLgRpVlZ2heeeOpTgvEnG/yHL9q1keUu5ILQ6s2qpLU=
-github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220308060532-714cd5c18552 h1:5YpK44u/Ou4FTdzRvQy3iZiNE5W2E91j7OK/65V+Nv0=
-github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220308060532-714cd5c18552/go.mod h1:yLgRpVlZ2heeeOpTgvEnG/yHL9q1keUu5ILQ6s2qpLU=
+github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220322085443-50e8f9bd208b h1:IoD7+sHQRLMouwHjhrOj5vhg+rPt/aKl4P+WiBZVHVk=
+github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220322085443-50e8f9bd208b/go.mod h1:yLgRpVlZ2heeeOpTgvEnG/yHL9q1keUu5ILQ6s2qpLU=
github.com/hyperledger/aries-framework-go/spi v0.0.0-20210320144851-40976de98ccf/go.mod h1:fDr9wW00GJJl1lR1SFHmJW8utIocdvjO5RNhAYS05EY=
github.com/hyperledger/aries-framework-go/spi v0.0.0-20210322152545-e6ebe2c79a2a/go.mod h1:fDr9wW00GJJl1lR1SFHmJW8utIocdvjO5RNhAYS05EY=
github.com/hyperledger/aries-framework-go/spi v0.0.0-20210409151411-eeeb8508bd87/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
@@ -216,8 +216,8 @@ github.com/hyperledger/aries-framework-go/spi v0.0.0-20210820153043-8b6f36d10ab9
github.com/hyperledger/aries-framework-go/spi v0.0.0-20210820175050-dcc7a225178d/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
github.com/hyperledger/aries-framework-go/spi v0.0.0-20211203210130-e927c9ed581a/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
github.com/hyperledger/aries-framework-go/spi v0.0.0-20220217153004-1622c70e5767/go.mod h1:4bD5c5fj5K7rkQurVa/8I8+TfNcI4bxIBzaUNcxTOTg=
-github.com/hyperledger/aries-framework-go/spi v0.0.0-20220308060532-714cd5c18552 h1:Rtho/IS7GbQJAkPdTABC7udQBMk1AQveYTgxPubZ474=
-github.com/hyperledger/aries-framework-go/spi v0.0.0-20220308060532-714cd5c18552/go.mod h1:4bD5c5fj5K7rkQurVa/8I8+TfNcI4bxIBzaUNcxTOTg=
+github.com/hyperledger/aries-framework-go/spi v0.0.0-20220322085443-50e8f9bd208b h1:Fo9mK3eB+TiYu2/hbTWtt0kWg9j1QRqnnbQQqaytJzE=
+github.com/hyperledger/aries-framework-go/spi v0.0.0-20220322085443-50e8f9bd208b/go.mod h1:4bD5c5fj5K7rkQurVa/8I8+TfNcI4bxIBzaUNcxTOTg=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210324232048-34ff560ed041/go.mod h1:eKGEEe+PJNDQo7kVif3sUKBWwnsQDkE3gD/QlpmukcQ=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210409151411-eeeb8508bd87/go.mod h1:JHzDtgJLd0134iLFXLxGBjJF+Z+TgiElA/5oVgMazts=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210421203733-b5dfd703a8fc/go.mod h1:asiCVCtH/nocWKhZRMz12aFgdUh8lRHqKis0M8Ei/4I=
diff --git a/scripts/check_go_integration.sh b/scripts/check_go_integration.sh
index 70d74fe78..af17afaf3 100755
--- a/scripts/check_go_integration.sh
+++ b/scripts/check_go_integration.sh
@@ -6,11 +6,6 @@
#
set -e
-# TODO: MacOS Monterey Golang fix, remove "MallocNanoZone=0" once https://github.com/golang/go/issues/49138 is resolved.
-# TODO: issue is now resolved in :https://github.com/golang/go/commit/5f6552018d1ec920c3ca3d459691528f48363c3c,
-# TODO" but will need to wait for next Go release.
-export MallocNanoZone=0
-
echo "Running aries-framework-go integration tests..."
PWD=`pwd`
cd test/bdd
diff --git a/scripts/check_unit.sh b/scripts/check_unit.sh
index 41e347377..bd380fee3 100755
--- a/scripts/check_unit.sh
+++ b/scripts/check_unit.sh
@@ -6,11 +6,6 @@
#
set -e
-# TODO: MacOS Monterey Golang fix, remove "MallocNanoZone=0" once https://github.com/golang/go/issues/49138 is resolved.
-# TODO: issue is now resolved in :https://github.com/golang/go/commit/5f6552018d1ec920c3ca3d459691528f48363c3c,
-# TODO" but will need to wait for next Go release.
-export MallocNanoZone=0
-
echo "Running $0"
GO_TEST_CMD="go test"
diff --git a/scripts/check_unit_wasm.sh b/scripts/check_unit_wasm.sh
index 548162607..8986fa524 100755
--- a/scripts/check_unit_wasm.sh
+++ b/scripts/check_unit_wasm.sh
@@ -6,11 +6,6 @@
#
set -e
-# TODO: MacOS Monterey Golang fix, remove "MallocNanoZone=0" once https://github.com/golang/go/issues/49138 is resolved.
-# TODO: issue is now resolved in :https://github.com/golang/go/commit/5f6552018d1ec920c3ca3d459691528f48363c3c,
-# TODO" but will need to wait for next Go release.
-export MallocNanoZone=0
-
echo "Running $0"
# Running wasm unit test
diff --git a/test/bdd/fixtures/agent-rest/.env b/test/bdd/fixtures/agent-rest/.env
index c1f6557a8..0f5e46400 100644
--- a/test/bdd/fixtures/agent-rest/.env
+++ b/test/bdd/fixtures/agent-rest/.env
@@ -115,7 +115,7 @@ COUCHDB_PORT=5984
# KMS
KMS_REST_IMAGE=ghcr.io/trustbloc-cicd/kms
-KMS_REST_TAG=v0.1.8-snapshot-2dff373
+KMS_REST_TAG=v0.1.8-snapshot-3f3ef05
# Remote JSON-LD context provider configuration
CONTEXT_PROVIDER_URL=https://file-server.example.com:9099/agent-startup-contexts.json
diff --git a/test/bdd/go.mod b/test/bdd/go.mod
index f15dc2760..190e54ed6 100644
--- a/test/bdd/go.mod
+++ b/test/bdd/go.mod
@@ -13,10 +13,10 @@ require (
github.com/fsouza/go-dockerclient v1.6.6
github.com/google/uuid v1.1.2
github.com/gorilla/mux v1.8.0
- github.com/hyperledger/aries-framework-go v0.1.8-0.20220308060532-714cd5c18552
- github.com/hyperledger/aries-framework-go/component/storage/leveldb v0.0.0-20220308060532-714cd5c18552
- github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220308060532-714cd5c18552
- github.com/hyperledger/aries-framework-go/spi v0.0.0-20220308060532-714cd5c18552
+ github.com/hyperledger/aries-framework-go v0.1.8-0.20220322085443-50e8f9bd208b
+ github.com/hyperledger/aries-framework-go/component/storage/leveldb v0.0.0-20220322085443-50e8f9bd208b
+ github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220322085443-50e8f9bd208b
+ github.com/hyperledger/aries-framework-go/spi v0.0.0-20220322085443-50e8f9bd208b
github.com/moby/sys/mount v0.2.0 // indirect
github.com/moby/term v0.0.0-20201110203204-bea5bbe245bf // indirect
github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2
@@ -48,7 +48,6 @@ require (
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/snappy v0.0.3 // indirect
github.com/google/tink/go v1.6.1-0.20210519071714-58be99b3c4d0 // indirect
- github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220217153004-1622c70e5767 // indirect
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a // indirect
github.com/kawamuray/jsonpath v0.0.0-20201211160320-7483bafabd7e // indirect
github.com/kilic/bls12-381 v0.1.1-0.20210503002446-7b7597926c69 // indirect
diff --git a/test/bdd/go.sum b/test/bdd/go.sum
index b64c030f9..85dc5a153 100644
--- a/test/bdd/go.sum
+++ b/test/bdd/go.sum
@@ -277,7 +277,7 @@ github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKe
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
-github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220308060532-714cd5c18552/go.mod h1:eIac5lubCy3tw6D0sTluM5U6Bw3inBwUfjX17o2U7PE=
+github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220322085443-50e8f9bd208b/go.mod h1:eIac5lubCy3tw6D0sTluM5U6Bw3inBwUfjX17o2U7PE=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
diff --git a/test/component/go.mod b/test/component/go.mod
index a2df2b7d8..8c8075644 100644
--- a/test/component/go.mod
+++ b/test/component/go.mod
@@ -8,6 +8,12 @@ go 1.17
require (
github.com/google/uuid v1.1.2
- github.com/hyperledger/aries-framework-go/spi v0.0.0-20211203210130-e927c9ed581a
+ github.com/hyperledger/aries-framework-go/spi v0.0.0-20220322085443-50e8f9bd208b
github.com/stretchr/testify v1.6.1
)
+
+require (
+ github.com/davecgh/go-spew v1.1.0 // indirect
+ github.com/pmezard/go-difflib v1.0.0 // indirect
+ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
+)
diff --git a/test/component/go.sum b/test/component/go.sum
index 93b729abd..7bc691096 100644
--- a/test/component/go.sum
+++ b/test/component/go.sum
@@ -2,8 +2,8 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/hyperledger/aries-framework-go/spi v0.0.0-20211203210130-e927c9ed581a h1:Nt9R2X9ya7S+h3blPwo085//C6C9JkKcHLegjUSD9wE=
-github.com/hyperledger/aries-framework-go/spi v0.0.0-20211203210130-e927c9ed581a/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
+github.com/hyperledger/aries-framework-go/spi v0.0.0-20220322085443-50e8f9bd208b h1:Fo9mK3eB+TiYu2/hbTWtt0kWg9j1QRqnnbQQqaytJzE=
+github.com/hyperledger/aries-framework-go/spi v0.0.0-20220322085443-50e8f9bd208b/go.mod h1:4bD5c5fj5K7rkQurVa/8I8+TfNcI4bxIBzaUNcxTOTg=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
From 071ce8fc905cde679b1b844a3199fc909b5cbf30 Mon Sep 17 00:00:00 2001
From: Filip Burlacu
Date: Fri, 25 Mar 2022 21:24:08 -0400
Subject: [PATCH 14/54] fix: outbound didcomm v2 messages always have 'body'
and 'from' fields (#3209)
Signed-off-by: Filip Burlacu
---
pkg/didcomm/common/middleware/middleware.go | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/pkg/didcomm/common/middleware/middleware.go b/pkg/didcomm/common/middleware/middleware.go
index abddc721f..f1ccc7e57 100644
--- a/pkg/didcomm/common/middleware/middleware.go
+++ b/pkg/didcomm/common/middleware/middleware.go
@@ -77,6 +77,7 @@ type rotatePayload struct {
const (
fromPriorJSONKey = "from_prior"
fromDIDJSONKey = "from"
+ bodyJSONKey = "body"
initialStateParam = "initialState"
)
@@ -160,6 +161,16 @@ func (h *DIDCommMessageMiddleware) HandleOutboundMessage(msg didcomm.DIDCommMsgM
return msg
}
+ // if there's no from DID, add a from DID.
+ if _, ok := msg[fromDIDJSONKey]; !ok {
+ msg[fromDIDJSONKey] = rec.MyDID
+ }
+
+ // if there's no body, add a body.
+ if _, ok := msg[bodyJSONKey]; !ok {
+ msg[bodyJSONKey] = map[string]interface{}{}
+ }
+
if rec.MyDIDRotation != nil {
msg[fromPriorJSONKey] = rec.MyDIDRotation.FromPrior
}
From 00dcf5617882a839f01fe289ce448fcc4499ff2c Mon Sep 17 00:00:00 2001
From: Sudesh Shetty
Date: Tue, 29 Mar 2022 17:16:59 -0400
Subject: [PATCH 15/54] chore: update vcwallet docs (#3211)
---
docs/vc_wallet.md | 113 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 111 insertions(+), 2 deletions(-)
diff --git a/docs/vc_wallet.md b/docs/vc_wallet.md
index 3febae4fc..869f3b454 100644
--- a/docs/vc_wallet.md
+++ b/docs/vc_wallet.md
@@ -8,6 +8,17 @@ Here are the major specification followed by aries verifiable credential wallet
* [Universal Wallet](https://w3c-ccg.github.io/universal-wallet-interop-spec/) - for wallet data models and interfaces.
* [Verifiable Presentation request Specifications](https://w3c-ccg.github.io/vp-request-spec/) - for credential queries.
* [Presentation Exchange](https://identity.foundation/presentation-exchange/) - for credential queries.
+* [WACI Presentation Exchange](https://identity.foundation/waci-presentation-exchange/): Wallet and credential interaction standards using DIDComm.
+* [Verifiable Credentials Data Model v1.1](https://www.w3.org/TR/vc-data-model/): For all the verifiable credential data model operations.
+* [JSON-LD v1.1](https://w3c.github.io/json-ld-syntax/): For JSON-based Serialization for Linked Data.
+* [Linked Data Proofs v1.0](https://w3c-ccg.github.io/ld-proofs/): For generating JSON-LD based linked data proofs.
+* [Decentralized Identifiers (DIDs) v1.0](https://w3c.github.io/did-core/): For signing and verifying verifiable credentials and presentations.
+* [WebKMS v0.7](https://w3c-ccg.github.io/webkms/): For implementing cryptographic key management systems for the wallet.
+* [Decentralized Identifier Resolution (DID Resolution) v0.2](https://w3c-ccg.github.io/did-resolution/): Followed for resolving various decentralized identifiers.
+* [Aries RFCS](#aries-rfcs): it follows many aries RFCs features like DIDComm, Out-Of-Band Messaging, Issue Credential Protocol, Present Proof Protocol, Messaging, Mediators etc.
+* [DIDComm V2](https://identity.foundation/didcomm-messaging/spec/): Version 2 of DID Communication protocol for secured communication between wallet and issuer/relying party.
+* [Credential Manifest](https://identity.foundation/credential-manifest/): Credential Manifests are a resource format that defines preconditional requirements, Issuer style preferences, Credential Style preferences and other facets User Agents utilize to help articulate and select the inputs necessary for processing and issuance of a specified credential.
+
## How it works
@@ -45,6 +56,8 @@ and they will be discussed in detail in data models and interfaces sections belo
The aries verifiable credential wallet provides various verifiable credentials operations based on universal wallet specifications like issue, prove, verify, derive etc.
Refer data models and interfaces sections below for more details.
+#### DIDComm Operations
+The aries verifiable credential wallet provides various DIDComm operations to perform secured exchange of credentials and other metadata between wallet and issuer/relying party.
## Creating and Updating Wallet Profiles
* A wallet profile with local KMS can be created by providing passphrase or secret lock service option.
@@ -603,7 +616,7 @@ Returns,
// accept an invitation from wallet, perform DID connect, send propose presentation message, wait and
// return request presentation message response from relying party.
- connectionID, err := myWallet.ProposePresentation(oobInvitation, wallet.WithPresentProofTimeout(80 * time.Second), wallet.WithFromDID("did:example:wallet"))
+ connectionID, err := myWallet.ProposePresentation(oobInvitation, wallet.WithInitiateTimeout(80 * time.Second), wallet.WithFromDID("did:example:wallet"))
// close wallet.
ok = myWallet.Close()
@@ -638,6 +651,97 @@ Returns,
```
+#### [ProposeCredential](https://w3c-ccg.github.io/universal-wallet-interop-spec/#proposecredential)
+Sends propose credential message from wallet to issuer, waits for offer credential message from issuer and returns incoming message.
+
+Params,
+* invitation - out of band invitation from inviter.
+* options - for sending propose presentation message.
+ * FromDID - option to provide customized from DID for sending propose presentation message.
+ * ConnectOptions - customized options for accepting invitation..
+ * Timeout - option to provide timeout duration to wait for offer credential message from issuer.
+
+Returns,
+* DIDCommMsg - offer credential message from issuer.
+* error - if operation fails.
+
+> Aries Go SDK Sample for sending propose credential message from wallet to issuer.
+ ```
+ // creating vcwallet instance.
+ myWallet, err := vcwallet.New(sampleUserID, ctx)
+
+ // open wallet.
+ err = myWallet.Open(...)
+
+ // accept an invitation from wallet, perform DID connect, send propose credential message, wait and
+ // return offer credential message response from issuer.
+ connectionID, err := myWallet.ProposeCredential(oobInvitation, wallet.WithInitiateTimeout(80 * time.Second), wallet.WithFromDID("did:example:wallet"))
+
+ // close wallet.
+ ok = myWallet.Close()
+
+ ```
+
+
+#### [RequestCredential](https://w3c-ccg.github.io/universal-wallet-interop-spec/#requestcredential)
+Sends request credential message from wallet to issuer and optionally waits for credential fulfillment.
+
+Params:
+* thID: thread ID (action ID) of offer credential message previously received.
+* concludeInteractionOptions: options to conclude interaction like presentation to be shared etc.
+ * rawPresentation - requesting credential from raw credential.
+ * presentation presenting proof or requesting credential from verifiable presentation instance. This option takes precedence when provided with other options.
+ * waitForDone - if provided then wallet will wait till it gets acknowledgement or problem report from other party.
+ * timeout - time duration to wait for status to be done or abanoned.
+
+Returns:
+* Credential interaction status containing status, redirectURL.
+* error if operation fails.
+
+> Aries Go SDK Sample for sending request credential message from wallet to issuer.
+ ```
+ // creating vcwallet instance.
+ myWallet, err := vcwallet.New(sampleUserID, ctx)
+
+ // open wallet.
+ err = myWallet.Open(...)
+
+ // send request credential message to issuer for ongoing credential interaction.
+ connectionID, err := myWallet.RequestCredential(threadID, wallet.FromPresentation(application))
+
+ // close wallet.
+ ok = myWallet.Close()
+
+ ```
+
+#### ResolveCredentialManifest
+Resolves given credential manifest by credential fulfillment or credential.
+Supports: https://identity.foundation/credential-manifest/
+
+Params,
+* manifest: Credential manifest data model in raw format.
+* resolve: to provide credential fulfillment or credential to resolve.
+
+Returns,
+* list of resolved descriptors.
+* error if operation fails.
+
+> Aries Go SDK Sample for resolving credential manifest by fulfillment.
+ ```
+ // creating vcwallet instance.
+ myWallet, err := vcwallet.New(sampleUserID, ctx)
+
+ // open wallet.
+ err = myWallet.Open(...)
+
+ // resolve credential manifest by raw credential fulfillment.
+ connectionID, err := myWallet.ResolveCredentialManifest(threadID, wallet.ResolveRawFulfillment(fulfillment))
+
+ // close wallet.
+ ok = myWallet.Close()
+
+ ```
+
## Controller Bindings
Aries command controller supports all verifiable credential wallet features with many more customization options like Authorization Capabilities (ZCAP-LD) feature for wallet's EDV and WebKMS components.
@@ -732,12 +836,17 @@ let requestPresentationMsg = await agent.vcwallet.proposePresentation({userID, a
// send present proof message from wallet for WACI share flow.
await agent.vcwallet.presentProof({userID, auth, threadID, presentation})
+// accept invitation, send propose credential message and wait for offer presentation.
+let offer = await wallet.proposeCredential(invitation, "did:example:holder", someTimeout)
+
+// send request credential message, wait for ack and return credential fulfillment.
+let fulfilment = await wallet.requestCredential(thID, presentation, waitForAck, someTimeout)
+
// close wallet
await agent.vcwallet.close({userID})
```
-
#### REST
Refer Aries Open API specifications for ``vcwallet`` operation ID.
From 1c2d9d65aea4609e90813f8081d6dd4d1d167f14 Mon Sep 17 00:00:00 2001
From: Baha <29608896+Baha-sk@users.noreply.github.com>
Date: Wed, 30 Mar 2022 09:33:50 -0400
Subject: [PATCH 16/54] chore: release 0.1.8 (#3210)
Signed-off-by: Baha Shaaban
---
.github/workflows/version_var.sh | 2 +-
CHANGELOG.md | 20 ++++++++++++++++++++
2 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/version_var.sh b/.github/workflows/version_var.sh
index b4a917449..ecb27664a 100644
--- a/.github/workflows/version_var.sh
+++ b/.github/workflows/version_var.sh
@@ -6,7 +6,7 @@
# Release Parameters
BASE_VERSION=0.1.8
-IS_RELEASE=false
+IS_RELEASE=true
ARCH=$(go env GOARCH)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 15f63f448..0e7e95e8a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,23 @@
+# 0.1.8
+
+## March 29, 2022
+
+- DIDCommV2 full support:
+ - Updated to V2 message structure
+ - OOB V2
+ - Issue Credential V3, Present Proof V3
+ - Mediator protocol support for DIDComm V2
+ - DID Rotation
+- Universal Wallet:
+ - WACI Issuance
+ - WACI Presentation
+ - Credential Manifest support & minor improvements
+- Aries RFCs / Interop
+ - Web-redirect support in issue-credential and present-proof protocols (V2 and V3)
+ - Media type profile support
+ - Various minor fixes
+- Fixes and improvements to Crypto, KMS, VDR, Verifiable Credential, Storage, and other components
+
# 0.1.7
## September 14, 2021
From 07042d78580cddf84bed93a5e14477ad25fc856b Mon Sep 17 00:00:00 2001
From: Baha <29608896+Baha-sk@users.noreply.github.com>
Date: Wed, 30 Mar 2022 10:06:27 -0400
Subject: [PATCH 17/54] chore: complete release 0.1.8 and prepare 0.1.9 (#3212)
Signed-off-by: Baha Shaaban
---
.github/workflows/version_var.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/version_var.sh b/.github/workflows/version_var.sh
index ecb27664a..ff8d12e65 100644
--- a/.github/workflows/version_var.sh
+++ b/.github/workflows/version_var.sh
@@ -5,8 +5,8 @@
#
# Release Parameters
-BASE_VERSION=0.1.8
-IS_RELEASE=true
+BASE_VERSION=0.1.9
+IS_RELEASE=false
ARCH=$(go env GOARCH)
From be0a5156266cee730b6e42d94c328e1022376aa7 Mon Sep 17 00:00:00 2001
From: Sudesh Shetty
Date: Thu, 7 Apr 2022 09:43:45 -0400
Subject: [PATCH 18/54] chore: updates to standards doc (#3215)
- added credential manifest specification reference
Signed-off-by: sudesh.shetty
---
docs/concepts/02_standards.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/concepts/02_standards.md b/docs/concepts/02_standards.md
index 3414dcb99..1b1405635 100644
--- a/docs/concepts/02_standards.md
+++ b/docs/concepts/02_standards.md
@@ -17,7 +17,7 @@ Notable ones are,
Mainly used in [Present Proof Protocol](00_what_is_hl_aries.md#8-presentproof-protocol) and [Aries Verifiable Credential Wallet](../vc_wallet.md) implementation.
* [Confidential Storage v0.1](https://identity.foundation/confidential-storage/): For secured storage implementation, also know as Encrypted Data Vault.
* [WACI Presentation Exchange](https://identity.foundation/waci-presentation-exchange/): Wallet and credential interaction standards using DIDComm.
-
+* [Credential Manifest](https://identity.foundation/credential-manifest/): Credential Manifests are a resource format that defines preconditional requirements, Issuer style preferences, Credential Style preferences and other facets User Agents utilize to help articulate and select the inputs necessary for processing and issuance of a specified credential.
### W3C Standards
From dce9dbba57f6c693c28c3951a57b89dbba02b5c4 Mon Sep 17 00:00:00 2001
From: Firas Qutishat
Date: Mon, 11 Apr 2022 16:29:32 -0400
Subject: [PATCH 19/54] chore: rename operationRequest to operation
Signed-off-by: Firas Qutishat
---
pkg/doc/did/doc.go | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/pkg/doc/did/doc.go b/pkg/doc/did/doc.go
index 70a4a6bfe..03bb2ee7c 100644
--- a/pkg/doc/did/doc.go
+++ b/pkg/doc/did/doc.go
@@ -180,15 +180,15 @@ type MethodMetadata struct {
// AnchorOrigin is anchor origin.
AnchorOrigin string `json:"anchorOrigin,omitempty"`
// UnpublishedOperations unpublished operations
- UnpublishedOperations []*Operations `json:"unpublishedOperations,omitempty"`
+ UnpublishedOperations []*ProtocolOperation `json:"unpublishedOperations,omitempty"`
// PublishedOperations published operations
- PublishedOperations []*Operations `json:"publishedOperations,omitempty"`
+ PublishedOperations []*ProtocolOperation `json:"publishedOperations,omitempty"`
}
-// Operations info.
-type Operations struct {
- // OperationRequest is operation request.
- OperationRequest string `json:"operationRequest,omitempty"`
+// ProtocolOperation info.
+type ProtocolOperation struct {
+ // Operation is operation request.
+ Operation string `json:"operation,omitempty"`
// ProtocolVersion is protocol version.
ProtocolVersion int `json:"protocolVersion,omitempty"`
// TransactionNumber is transaction number.
From 58f502b3af45dab533f298c49d5c1f342b9e622b Mon Sep 17 00:00:00 2001
From: Derek Trider
Date: Tue, 5 Apr 2022 21:48:58 -0400
Subject: [PATCH 20/54] docs: Storage compatibility matrix
Added a document that lists what storage providers we have implemented and what functionality is implemented. Also made some small additions to the storage interface documentation.
Signed-off-by: Derek Trider
---
docs/storage_compatibility_matrix.md | 69 ++++++++++++++++++++++++++++
spi/storage/storage.go | 2 +
2 files changed, 71 insertions(+)
create mode 100644 docs/storage_compatibility_matrix.md
diff --git a/docs/storage_compatibility_matrix.md b/docs/storage_compatibility_matrix.md
new file mode 100644
index 000000000..38913c3f6
--- /dev/null
+++ b/docs/storage_compatibility_matrix.md
@@ -0,0 +1,69 @@
+# Storage Compatibility Matrix
+
+Aries-Framework-Go (this repo) and [Aries-Framework-Go-Ext](https://github.com/hyperledger/aries-framework-go-ext) have a number of storage providers that implement the [Aries storage interfaces](../spi/storage/storage.go).
+
+This document lists the storage provider implementations we have and what functionality is currently implemented/supported.
+
+The functions defined in the interfaces can be categorized as either "core" or "extended" functionality.
+
+✓ = Implemented
+
+X = Not implemented (but could be)
+
+Unsupported = Not implemented (and not currently supported by the underlying database/technology/spec)
+
+## Core Functionality
+
+These are the functions that the Aries agent currently uses. For a storage provider implementation to work in an Aries agent, it needs to support **all** the functions below.
+
+| | [MongoDB](https://github.com/hyperledger/aries-framework-go-ext/blob/main/component/storage/mongodb) | [CouchDB](https://github.com/hyperledger/aries-framework-go-ext/blob/main/component/storage/couchdb) | [EDV](https://github.com/hyperledger/aries-framework-go/tree/main/component/storage/edv) | [MySQL](https://github.com/hyperledger/aries-framework-go-ext/tree/main/component/storage/mysql) | [IndexedDB](https://github.com/hyperledger/aries-framework-go/tree/main/component/storage/indexeddb) | [LevelDB](https://github.com/hyperledger/aries-framework-go/tree/main/component/storage/leveldb) | [In-Memory](https://github.com/hyperledger/aries-framework-go/tree/main/component/storageutil/mem) | [PostgreSQL](https://github.com/hyperledger/aries-framework-go-ext/tree/main/component/storage/postgresql) |
+|---------------------------|------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------|
+| Provider - OpenStore | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
+| Provider - SetStoreConfig | ✓ | ✓ | ✓* | ✓** | ✓*** | ✓ | ✓ | ✓**** |
+| Provider - Close | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
+| Store - Put | ✓ | ✓ | ✓ | ✓** | ✓*** | ✓ | ✓ | ✓**** |
+| Store - Get | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
+| Store - Query Using 1 Tag | ✓ | ✓ | ✓ | ✓** | ✓*** | ✓ | ✓ | X***** |
+| Store - Delete | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
+| Store - Close | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
+| Iterator - Next | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
+| Iterator - Key | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
+| Iterator - Value | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
+| Iterator - Close | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
+
+\* This method is more or less a no-op since EDV doesn't need this. Store config is just stored in-memory for now - see [here](https://github.com/hyperledger/aries-framework-go-ext/issues/2492) for more info. Since the Aries agent doesn't currently use GetStoreConfig, this isn't an issue for Aries usages.
+
+\*\* Current tagging/querying mechanism is unoptimized and not recommended for production use as-is. See [here](https://github.com/hyperledger/aries-framework-go-ext/issues/67) for more info.
+
+\*\*\* Current tagging/querying mechanism is unoptimized and not recommended for production use as-is. See [here](https://github.com/hyperledger/aries-framework-go-ext/issues/2540) for more info.
+
+\*\*\*\* There are some limitations with the current implementation of these methods. See [here](https://github.com/hyperledger/aries-framework-go-ext/issues/229) for more info.
+
+\*\*\*\*\* Tag name only queries have been implemented, but not tag name + value queries. Both types of queries are used by an Aries agent. See [here](https://github.com/hyperledger/aries-framework-go-ext/issues/229) for more info.
+
+## Extended Functionality
+
+The Aries agent does not currently make use of these functions, but they may be useful in building your own application.
+
+| | [MongoDB](https://github.com/hyperledger/aries-framework-go-ext/blob/main/component/storage/mongodb) | [CouchDB](https://github.com/hyperledger/aries-framework-go-ext/blob/main/component/storage/couchdb) | [EDV](https://github.com/hyperledger/aries-framework-go/tree/main/component/storage/edv) | [MySQL](https://github.com/hyperledger/aries-framework-go-ext/tree/main/component/storage/mysql) | [IndexedDB](https://github.com/hyperledger/aries-framework-go/tree/main/component/storage/indexeddb) | [LevelDB](https://github.com/hyperledger/aries-framework-go/tree/main/component/storage/leveldb) | [In-Memory](https://github.com/hyperledger/aries-framework-go/tree/main/component/storageutil/mem) | [PostgreSQL](https://github.com/hyperledger/aries-framework-go-ext/tree/main/component/storage/postgresql) |
+|-------------------------------------------------|------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------|
+| Provider - GetStoreConfig | ✓ | ✓ | ✓* | ✓** | ✓*** | ✓*** | ✓ | X |
+| Provider - GetOpenStores | ✓ | ✓ | ✓ | X | X | ✓ | ✓ | X |
+| Store - GetTags | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | X |
+| Store - GetBulk | ✓ | ✓ | ✓ | X | X | ✓**** | ✓ | X |
+| Store - Query Using Range Operators (<,<=,>,=>) | ✓ | X | Unsupported | X | X | X | X | X |
+| Store - Query Using Multiple Tags | ✓ | X | X | X | X | X | X | X |
+| Store - Query Using Custom Pagination | ✓ | ✓ | Unsupported | X | X | X | X | X |
+| Store - Query Using Custom Sorting | ✓ | ✓ | Unsupported | X | X | X | X | X |
+| Store - Batch | ✓ | ✓ | ✓ | ✓ | ✓ | ✓**** | ✓ | X |
+| Store - Flush | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
+| Iterator - Tags | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | X |
+| Iterator - TotalItems | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | X |
+
+\* Only returns store config if it's still in memory. Can't be used to report whether the underlying database exists.
+
+\*\* Doesn't currently check the underlying data for existence (looks at in-memory stores instead). See [here](https://github.com/hyperledger/aries-framework-go-ext/issues/167) for more info.
+
+\*\*\* Doesn't currently check the underlying data for existence (looks at in-memory stores instead). See [here](https://github.com/hyperledger/aries-framework-go/issues/2948) for more info.
+
+\*\*\*\* Unoptimized implementation. See [here](https://github.com/hyperledger/aries-framework-go/issues/2605) for more info.
\ No newline at end of file
diff --git a/spi/storage/storage.go b/spi/storage/storage.go
index 4e112d8b1..ec38d7351 100644
--- a/spi/storage/storage.go
+++ b/spi/storage/storage.go
@@ -194,6 +194,7 @@ type Store interface {
// GetTags fetches all tags associated with the given key.
// If key cannot be found, then an error wrapping ErrDataNotFound will be returned.
// If key is empty, then an error will be returned.
+ // As of writing, aries-framework-go code does not use this, but it may be useful for custom solutions.
GetTags(key string) ([]Tag, error)
// GetBulk fetches the values associated with the given keys.
@@ -225,6 +226,7 @@ type Store interface {
// enabled and a key is used that already exists in the database.
// Depending on the implementation, this method may be faster than repeated Put and/or Delete calls.
// If any of the given keys are empty, or the operations slice is empty or nil, then an error will be returned.
+ // As of writing, aries-framework-go code does not use this, but it may be useful for custom solutions.
Batch(operations []Operation) error
// Flush forces any queued up Put and/or Delete operations to execute.
From 2825074751ea09840f947f0cf37dab3a8141d177 Mon Sep 17 00:00:00 2001
From: Derek Trider
Date: Mon, 11 Apr 2022 13:27:20 -0400
Subject: [PATCH 21/54] docs: Updated storage interface documentation
Updated the documentation for the Put method to indicate that in the set of tags used on a single Put call, those tags must have unique tag names. The reason for this is because several of our major storage implementations in aries-framework-go-ext have this implementation, so this note was added to help ensure consistent behaviour.
Signed-off-by: Derek Trider
---
spi/storage/storage.go | 1 +
1 file changed, 1 insertion(+)
diff --git a/spi/storage/storage.go b/spi/storage/storage.go
index ec38d7351..8769b9230 100644
--- a/spi/storage/storage.go
+++ b/spi/storage/storage.go
@@ -184,6 +184,7 @@ type Store interface {
// with data put in and data retrieved, as the marshalled representation may be different - always unmarshal data
// first before comparing.
// If key is empty or value is nil, then an error will be returned.
+ // A single key-value pair cannot have multiple tags that share the same tag name.
Put(key string, value []byte, tags ...Tag) error
// Get fetches the value associated with the given key.
From dbf49cb995406a1c6c02f4bd9da8b263de13529f Mon Sep 17 00:00:00 2001
From: Rolson Quadras
Date: Wed, 13 Apr 2022 13:32:50 -0400
Subject: [PATCH 22/54] docs: [readme-text] replace digital-hub with
encrypted-data-vault (#3220)
Signed-off-by: Rolson Quadras
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 1bad5d4ea..b505ea7fb 100644
--- a/README.md
+++ b/README.md
@@ -15,7 +15,7 @@ We aim to provide Go implementations of:
- Decentralized identity standards including [W3C decentralized identifiers](https://w3c.github.io/did-core/) (DIDs), [W3C DID resolution](https://w3c-ccg.github.io/did-resolution/), and [W3C verifiable credentials](https://w3c.github.io/vc-data-model/).
- Decentralized data communication protocols anchored in DIDs: [DIDComm](https://github.com/hyperledger/aries-rfcs/blob/master/concepts/0005-didcomm).
-- A pluggable dependency framework, where implementors can customize primitives via Service Provider Interfaces (SPIs). We have a "batteries included" model where default primitives are included -- such as a [key management system (KMS)](docs/kms_secretlock.md), crypto, data storage, digital hub integration, etc.
+- A pluggable dependency framework, where implementors can customize primitives via Service Provider Interfaces (SPIs). We have a "batteries included" model where default primitives are included -- such as a [key management system (KMS)](docs/kms_secretlock.md), crypto, data storage, encrypted data vault integration, etc.
We aim to enable usage of our protocol implementations in a wide variety of edge and cloud environments including servers, browsers, mobile, and devices.
API bindings are supplied to enable these environments including:
From 64e00da62d16c6ddad8ddf1124032da98d073cd5 Mon Sep 17 00:00:00 2001
From: Firas Qutishat
Date: Fri, 22 Apr 2022 06:53:05 -0400
Subject: [PATCH 23/54] chore: add revocation list 2021 context
Signed-off-by: Firas Qutishat
---
pkg/doc/ldcontext/embed/embed_contexts.go | 7 +++
.../revocationList2021.jsonld | 55 +++++++++++++++++++
2 files changed, 62 insertions(+)
create mode 100644 pkg/doc/ldcontext/embed/third_party/w3c-ccg.github.io/revocationList2021.jsonld
diff --git a/pkg/doc/ldcontext/embed/embed_contexts.go b/pkg/doc/ldcontext/embed/embed_contexts.go
index a4b1f980a..0ee313785 100644
--- a/pkg/doc/ldcontext/embed/embed_contexts.go
+++ b/pkg/doc/ldcontext/embed/embed_contexts.go
@@ -48,6 +48,8 @@ var (
credentialApplication []byte
//go:embed third_party/digitalbazaar.github.io/ed25519-signature-2020-v1.jsonld
ed255192020 []byte
+ //go:embed third_party/w3c-ccg.github.io/revocationList2021.jsonld
+ revocationList2021 []byte
)
// Contexts contains JSON-LD contexts embedded into a Go binary.
@@ -112,6 +114,11 @@ var Contexts = []ldcontext.Document{ //nolint:gochecknoglobals
DocumentURL: "https://w3c-ccg.github.io/vc-status-rl-2020/contexts/vc-revocation-list-2020/v1.jsonld",
Content: revocationList2020,
},
+ {
+ URL: "https://w3id.org/vc-revocation-list-2021/v1",
+ DocumentURL: "https://w3c-ccg.github.io/vc-status-list-2021/contexts/v1.jsonld",
+ Content: revocationList2021,
+ },
{
URL: "https://identity.foundation/presentation-exchange/submission/v1",
DocumentURL: "https://identity.foundation/presentation-exchange/submission/v1/",
diff --git a/pkg/doc/ldcontext/embed/third_party/w3c-ccg.github.io/revocationList2021.jsonld b/pkg/doc/ldcontext/embed/third_party/w3c-ccg.github.io/revocationList2021.jsonld
new file mode 100644
index 000000000..4027c1d49
--- /dev/null
+++ b/pkg/doc/ldcontext/embed/third_party/w3c-ccg.github.io/revocationList2021.jsonld
@@ -0,0 +1,55 @@
+{
+ "@context": {
+ "@protected": true,
+
+ "StatusList2021Credential": {
+ "@id":
+ "https://w3id.org/vc/status-list#StatusList2021Credential",
+ "@context": {
+ "@protected": true,
+
+ "id": "@id",
+ "type": "@type",
+
+ "description": "http://schema.org/description",
+ "name": "http://schema.org/name"
+ }
+ },
+
+ "StatusList2021": {
+ "@id":
+ "https://w3id.org/vc/status-list#StatusList2021",
+ "@context": {
+ "@protected": true,
+
+ "id": "@id",
+ "type": "@type",
+
+ "statusPurpose":
+ "https://w3id.org/vc/status-list#statusPurpose",
+ "encodedList": "https://w3id.org/vc/status-list#encodedList"
+ }
+ },
+
+ "StatusList2021Entry": {
+ "@id":
+ "https://w3id.org/vc/status-list#StatusList2021Entry",
+ "@context": {
+ "@protected": true,
+
+ "id": "@id",
+ "type": "@type",
+
+ "statusPurpose":
+ "https://w3id.org/vc/status-list#statusPurpose",
+ "statusListIndex":
+ "https://w3id.org/vc/status-list#statusListIndex",
+ "statusListCredential": {
+ "@id":
+ "https://w3id.org/vc/status-list#statusListCredential",
+ "@type": "@id"
+ }
+ }
+ }
+ }
+}
From fa563f13f8424ea65d8dbc2445c9c8a4890f93f8 Mon Sep 17 00:00:00 2001
From: Firas Qutishat
Date: Fri, 22 Apr 2022 07:50:13 -0400
Subject: [PATCH 24/54] fix: vc-revocation-list-2021 context
Signed-off-by: Firas Qutishat
---
pkg/doc/ldcontext/embed/embed_contexts.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pkg/doc/ldcontext/embed/embed_contexts.go b/pkg/doc/ldcontext/embed/embed_contexts.go
index 0ee313785..95dbd89de 100644
--- a/pkg/doc/ldcontext/embed/embed_contexts.go
+++ b/pkg/doc/ldcontext/embed/embed_contexts.go
@@ -115,7 +115,7 @@ var Contexts = []ldcontext.Document{ //nolint:gochecknoglobals
Content: revocationList2020,
},
{
- URL: "https://w3id.org/vc-revocation-list-2021/v1",
+ URL: "https://w3id.org/vc/status-list/2021/v1",
DocumentURL: "https://w3c-ccg.github.io/vc-status-list-2021/contexts/v1.jsonld",
Content: revocationList2021,
},
From 2ac4fa7928cb4bff30947a44a857f8d925a6920b Mon Sep 17 00:00:00 2001
From: Derek Trider
Date: Mon, 25 Apr 2022 13:50:23 -0400
Subject: [PATCH 25/54] feat: In-memory store "ping" method
The method always returns nil. It's there just to allow it to implement a "Pinger" sort of interface which may be defined somewhere.
Signed-off-by: Derek Trider
---
component/storageutil/mem/mem.go | 6 ++++++
component/storageutil/mem/mem_test.go | 7 +++++++
2 files changed, 13 insertions(+)
diff --git a/component/storageutil/mem/mem.go b/component/storageutil/mem/mem.go
index 612248965..c2ffebe69 100644
--- a/component/storageutil/mem/mem.go
+++ b/component/storageutil/mem/mem.go
@@ -132,6 +132,12 @@ func (p *Provider) Close() error {
return nil
}
+// Ping always returns nil. It's here just to allow it to implement a "Pinger" sort of interface which may be defined
+// somewhere and implemented by other storage implementations that use a remote database.
+func (p *Provider) Ping() error {
+ return nil
+}
+
func (p *Provider) removeStore(name string) {
p.lock.Lock()
defer p.lock.Unlock()
diff --git a/component/storageutil/mem/mem_test.go b/component/storageutil/mem/mem_test.go
index 1ccf9506c..ac1646306 100644
--- a/component/storageutil/mem/mem_test.go
+++ b/component/storageutil/mem/mem_test.go
@@ -60,3 +60,10 @@ func TestMemIterator(t *testing.T) {
require.EqualError(t, err, "iterator is exhausted")
require.Nil(t, tags)
}
+
+func TestProvider_Ping(t *testing.T) {
+ provider := mem.NewProvider()
+
+ err := provider.Ping()
+ require.NoError(t, err)
+}
From 04d0d9011562b6e0063005f0b2a760e917641c42 Mon Sep 17 00:00:00 2001
From: Baha <29608896+Baha-sk@users.noreply.github.com>
Date: Tue, 26 Apr 2022 17:36:01 -0400
Subject: [PATCH 26/54] refactor: endpoint as object, goal-code with underscore
(#3223)
* refactor: endpoint change from string to struct
Following this DIDcomm V2 spec udpate:
https://github.com/decentralized-identity/didcomm-messaging/pull/352
The endpoint field is now a structure containing a URI, Accept and the RoutingKeys.
Signed-off-by: Baha Shaaban
* refactor: goal-code with underscore
Following this DIDcomm V2 spec udpate:
https://github.com/decentralized-identity/didcomm-messaging/pull/363
goal-code is now goal_code.
Signed-off-by: Baha Shaaban
---
.../pkg/wrappers/command/outofband_test.go | 2 +-
.../pkg/wrappers/command/outofbandv2_test.go | 2 +-
.../pkg/wrappers/rest/outofband_test.go | 4 +-
pkg/client/connection/client.go | 22 +++--
pkg/client/didexchange/client.go | 1 -
pkg/client/didexchange/client_test.go | 7 +-
pkg/client/messaging/client_test.go | 33 ++++---
pkg/client/outofband/client.go | 15 ++--
pkg/client/outofband/client_test.go | 59 ++++++++-----
pkg/common/model/endpoint.go | 17 ++++
.../command/didexchange/command_test.go | 7 +-
pkg/controller/command/messaging/command.go | 9 +-
.../rest/didexchange/operation_test.go | 7 +-
pkg/didcomm/common/middleware/middleware.go | 19 +++--
pkg/didcomm/common/service/destination.go | 5 +-
.../common/service/destination_default.go | 27 +++---
.../common/service/destination_test.go | 21 +++--
pkg/didcomm/dispatcher/outbound/outbound.go | 41 ++++-----
.../dispatcher/outbound/outbound_test.go | 74 ++++++++++------
pkg/didcomm/protocol/didexchange/service.go | 49 ++++++-----
.../protocol/didexchange/service_test.go | 9 +-
pkg/didcomm/protocol/didexchange/states.go | 32 ++++---
.../protocol/didexchange/states_test.go | 85 +++++++++++--------
pkg/didcomm/protocol/introduce/models.go | 2 +-
.../protocol/issuecredential/params_test.go | 4 +-
.../protocol/outofband/service_test.go | 30 ++++---
pkg/didcomm/protocol/outofbandv2/models.go | 2 +-
pkg/didcomm/protocol/outofbandv2/service.go | 14 +--
.../protocol/outofbandv2/service_test.go | 4 +-
pkg/didcomm/transport/http/outbound.go | 2 +-
pkg/didcomm/transport/http/outbound_test.go | 3 +-
pkg/didcomm/transport/ws/outbound.go | 6 +-
pkg/didcomm/transport/ws/outbound_test.go | 2 +-
pkg/didcomm/transport/ws/support_test.go | 5 +-
pkg/doc/did/doc.go | 39 +++++++--
pkg/doc/did/doc_test.go | 35 ++++----
pkg/doc/did/schema.go | 78 +++++++++++++++--
.../verifiable/credential_jwt_proof_test.go | 3 +-
pkg/framework/aries/framework_test.go | 9 +-
pkg/framework/context/context_test.go | 8 +-
pkg/mock/diddoc/mock_diddoc.go | 57 ++++++++-----
pkg/mock/vdr/mock_registry.go | 13 +--
pkg/store/connection/connection_lookup.go | 7 +-
pkg/store/did/store_test.go | 3 +-
pkg/vdr/peer/creator.go | 4 +-
pkg/vdr/peer/creator_test.go | 25 +++---
pkg/vdr/verifiable_compat_test.go | 3 +-
pkg/wallet/invitation.go | 2 +-
.../features/waci_issuance_didcomm_v1.feature | 2 +-
.../features/waci_issuance_didcomm_v2.feature | 2 +-
.../pkg/connection/connection_sdk_steps.go | 1 -
.../waci_issuance_didcomm_v1_sdk_steps.go | 2 +-
.../waci_issuance_didcomm_v2_sdk_steps.go | 2 +-
53 files changed, 580 insertions(+), 336 deletions(-)
create mode 100644 pkg/common/model/endpoint.go
diff --git a/cmd/aries-agent-mobile/pkg/wrappers/command/outofband_test.go b/cmd/aries-agent-mobile/pkg/wrappers/command/outofband_test.go
index c063d22a9..080fe2eb9 100644
--- a/cmd/aries-agent-mobile/pkg/wrappers/command/outofband_test.go
+++ b/cmd/aries-agent-mobile/pkg/wrappers/command/outofband_test.go
@@ -124,7 +124,7 @@ func TestOutOfBand_CreateInvitation(t *testing.T) {
mockResponse := `{"invitation":{"@id":"2429a5d3-c500-4647-9bb5-e34207bce406",
"@type":"https://didcomm.org/out-of-band/1.0/invitation","label":"label","goal":"goal",
-"goal-code":"goal_code","service":["s1"],"protocols":["s1"]}}
+"goal_code":"goal_code","service":["s1"],"protocols":["s1"]}}
`
fakeHandler := mockCommandRunner{data: []byte(mockResponse)}
controller.handlers[outofband.CreateInvitation] = fakeHandler.exec
diff --git a/cmd/aries-agent-mobile/pkg/wrappers/command/outofbandv2_test.go b/cmd/aries-agent-mobile/pkg/wrappers/command/outofbandv2_test.go
index 306a6c71c..ba9b441bb 100644
--- a/cmd/aries-agent-mobile/pkg/wrappers/command/outofbandv2_test.go
+++ b/cmd/aries-agent-mobile/pkg/wrappers/command/outofbandv2_test.go
@@ -56,7 +56,7 @@ func TestOutOfBandV2_CreateInvitation(t *testing.T) {
mockResponse := `{"invitation":{"@id":"2429a5d3-c500-4647-9bb5-e34207bce406",
"@type":"https://didcomm.org/out-of-band/2.0/invitation","label":"label","body":{
-"goal":"goal","goal-code":"goal_code","accept":["didcomm/v2"]}}}
+"goal":"goal","goal_code":"goal_code","accept":["didcomm/v2"]}}}
`
fakeHandler := mockCommandRunner{data: []byte(mockResponse)}
controller.handlers[outofbandv2.CreateInvitation] = fakeHandler.exec
diff --git a/cmd/aries-agent-mobile/pkg/wrappers/rest/outofband_test.go b/cmd/aries-agent-mobile/pkg/wrappers/rest/outofband_test.go
index 2d19304a0..f4371545c 100644
--- a/cmd/aries-agent-mobile/pkg/wrappers/rest/outofband_test.go
+++ b/cmd/aries-agent-mobile/pkg/wrappers/rest/outofband_test.go
@@ -136,7 +136,7 @@ func TestOutOfBand_CreateInvitation(t *testing.T) {
reqData := `{"label":"label","goal":"goal","goal_code":"goal_code","service":["s1"],"protocols":["s1"]}`
mockResponse := `{"invitation":{"@id":"2429a5d3-c500-4647-9bb5-e34207bce406",
"@type":"https://didcomm.org/out-of-band/1.0/invitation","label":"label","goal":"goal",
-"goal-code":"goal_code","service":["s1"],"protocols":["s1"]}}
+"goal_code":"goal_code","service":["s1"],"protocols":["s1"]}}
`
controller.httpClient = &mockHTTPClient{
@@ -160,7 +160,7 @@ func TestOutOfBand_CreateRequest(t *testing.T) {
reqData := `{"label":"label","goal":"goal","goal_code":"goal_code","service":["s1"],
"attachments":[{"lastmod_time":"0001-01-01T00:00:00Z","data":{}}]}`
mockResponse := `{"invitation":{"@id":"26169718-f261-48f1-addd-67018977a89f",
-"@type":"https://didcomm.org/out-of-band/1.0/invitation","label":"label","goal":"goal","goal-code":"goal_code",
+"@type":"https://didcomm.org/out-of-band/1.0/invitation","label":"label","goal":"goal","goal_code":"goal_code",
"request~attach":[{"lastmod_time":"0001-01-01T00:00:00Z","data":{}}],"service":["s1"]}}`
controller.httpClient = &mockHTTPClient{
diff --git a/pkg/client/connection/client.go b/pkg/client/connection/client.go
index 5069fc805..9cfb5885b 100644
--- a/pkg/client/connection/client.go
+++ b/pkg/client/connection/client.go
@@ -11,6 +11,7 @@ import (
"github.com/google/uuid"
+ "github.com/hyperledger/aries-framework-go/pkg/common/model"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/middleware"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/peerdid"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/service"
@@ -105,15 +106,18 @@ func (c *Client) CreateConnectionV2(myDID, theirDID string, opts ...CreateConnec
connID := uuid.New().String()
connRec := connection.Record{
- ConnectionID: connID,
- State: connection.StateNameCompleted,
- TheirDID: theirDID,
- MyDID: myDID,
- ServiceEndPoint: destination.ServiceEndpoint,
- RecipientKeys: destination.RecipientKeys,
- RoutingKeys: destination.RoutingKeys,
- Namespace: connection.MyNSPrefix,
- DIDCommVersion: service.V2,
+ ConnectionID: connID,
+ State: connection.StateNameCompleted,
+ TheirDID: theirDID,
+ MyDID: myDID,
+ ServiceEndPoint: model.Endpoint{
+ URI: destination.ServiceEndpoint.URI,
+ Accept: destination.ServiceEndpoint.Accept,
+ RoutingKeys: destination.ServiceEndpoint.RoutingKeys,
+ },
+ RecipientKeys: destination.RecipientKeys,
+ Namespace: connection.MyNSPrefix,
+ DIDCommVersion: service.V2,
}
for _, opt := range opts {
diff --git a/pkg/client/didexchange/client.go b/pkg/client/didexchange/client.go
index c553d9d1e..3f2140163 100644
--- a/pkg/client/didexchange/client.go
+++ b/pkg/client/didexchange/client.go
@@ -437,7 +437,6 @@ func (c *Client) CreateConnection(myDID string, theirDID *did.Doc, options ...Co
conn.ServiceEndPoint = destination.ServiceEndpoint
conn.RecipientKeys = destination.RecipientKeys
- conn.RoutingKeys = destination.RoutingKeys
err = c.didexchangeSvc.CreateConnection(conn.Record, theirDID)
if err != nil {
diff --git a/pkg/client/didexchange/client_test.go b/pkg/client/didexchange/client_test.go
index a5575911a..474ad7226 100644
--- a/pkg/client/didexchange/client_test.go
+++ b/pkg/client/didexchange/client_test.go
@@ -21,6 +21,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/hyperledger/aries-framework-go/component/storageutil/mem"
+ "github.com/hyperledger/aries-framework-go/pkg/common/model"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/service"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/decorator"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/didexchange"
@@ -772,13 +773,13 @@ func TestClient_CreateConnection(t *testing.T) {
require.NoError(t, err)
// empty ServiceEndpoint to trigger CreateDestination error
- theirDID.Service[0].ServiceEndpoint = ""
+ theirDID.Service[0].ServiceEndpoint.URI = ""
_, err = c.CreateConnection(myDID.ID, theirDID,
WithTheirLabel(label), WithThreadID(threadID), WithParentThreadID(parentThreadID),
WithInvitationID(invitationID), WithInvitationDID(invitationDID), WithImplicit(implicit))
require.Contains(t, err.Error(), "createConnection: failed to create destination: "+
- "create destination: no service endpoint on didcomm service block in diddoc:")
+ "create destination: no service endpoint URI on didcomm service block in diddoc:")
})
}
@@ -1515,7 +1516,7 @@ func newPeerDID(t *testing.T) *did.Doc {
d, err := ctx.VDRegistry().Create(
peer.DIDMethod, &did.Doc{Service: []did.Service{{
Type: "did-communication",
- ServiceEndpoint: "http://agent.example.com/didcomm",
+ ServiceEndpoint: model.Endpoint{URI: "http://agent.example.com/didcomm"},
}}, VerificationMethod: []did.VerificationMethod{getSigningKey()}})
require.NoError(t, err)
diff --git a/pkg/client/messaging/client_test.go b/pkg/client/messaging/client_test.go
index 415103ffd..f33e8bf2a 100644
--- a/pkg/client/messaging/client_test.go
+++ b/pkg/client/messaging/client_test.go
@@ -18,6 +18,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/hyperledger/aries-framework-go/component/storageutil/mem"
+ "github.com/hyperledger/aries-framework-go/pkg/common/model"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/service"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/dispatcher"
"github.com/hyperledger/aries-framework-go/pkg/doc/did"
@@ -171,9 +172,11 @@ func TestCommand_Send(t *testing.T) { // nolint: gocognit, gocyclo
{
name: "send message to destination",
option: SendByDestination(&service.Destination{
- RecipientKeys: []string{"test"},
- ServiceEndpoint: "sdfsdf",
- RoutingKeys: []string{"test"},
+ RecipientKeys: []string{"test"},
+ ServiceEndpoint: model.Endpoint{
+ URI: "sdfsdf",
+ RoutingKeys: []string{"test"},
+ },
}),
},
}
@@ -266,9 +269,11 @@ func TestCommand_Send(t *testing.T) { // nolint: gocognit, gocyclo
name: "send message to destination",
option: []SendMessageOpions{
SendByDestination(&service.Destination{
- RecipientKeys: []string{"test"},
- ServiceEndpoint: "sdfsdf",
- RoutingKeys: []string{"test"},
+ RecipientKeys: []string{"test"},
+ ServiceEndpoint: model.Endpoint{
+ URI: "sdfsdf",
+ RoutingKeys: []string{"test"},
+ },
}),
WaitForResponse(context.Background(), "sample-response-type"),
},
@@ -417,9 +422,11 @@ func TestCommand_Send(t *testing.T) { // nolint: gocognit, gocyclo
{
name: "send message to destination - failure 1",
option: SendByDestination(&service.Destination{
- RecipientKeys: []string{"test"},
- ServiceEndpoint: "sdfsdf",
- RoutingKeys: []string{"test"},
+ RecipientKeys: []string{"test"},
+ ServiceEndpoint: model.Endpoint{
+ URI: "sdfsdf",
+ RoutingKeys: []string{"test"},
+ },
}),
messenger: &mocksvc.MockMessenger{ErrSendToDestination: fmt.Errorf("sample-err-01")},
errorMsg: "sample-err-01",
@@ -428,9 +435,11 @@ func TestCommand_Send(t *testing.T) { // nolint: gocognit, gocyclo
name: "send message to destination - failure 2",
kms: &mockkms.KeyManager{CrAndExportPubKeyErr: fmt.Errorf("sample-kmserr-01")},
option: SendByDestination(&service.Destination{
- RecipientKeys: []string{"test"},
- ServiceEndpoint: "sdfsdf",
- RoutingKeys: []string{"test"},
+ RecipientKeys: []string{"test"},
+ ServiceEndpoint: model.Endpoint{
+ URI: "sdfsdf",
+ RoutingKeys: []string{"test"},
+ },
}),
errorMsg: "sample-kmserr-01",
},
diff --git a/pkg/client/outofband/client.go b/pkg/client/outofband/client.go
index 88c1db24f..9a5fcbc10 100644
--- a/pkg/client/outofband/client.go
+++ b/pkg/client/outofband/client.go
@@ -12,6 +12,7 @@ import (
"github.com/google/uuid"
+ "github.com/hyperledger/aries-framework-go/pkg/common/model"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/service"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/decorator"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/didexchange"
@@ -417,7 +418,7 @@ func (c *Client) didServiceBlockFunc(p Provider) func(routerConnID string, accep
ID: uuid.New().String(),
Type: didCommServiceType,
RecipientKeys: []string{didKey},
- ServiceEndpoint: p.ServiceEndpoint(),
+ ServiceEndpoint: model.Endpoint{URI: p.ServiceEndpoint()},
}, nil
}
@@ -432,11 +433,13 @@ func (c *Client) didServiceBlockFunc(p Provider) func(routerConnID string, accep
}
return &did.Service{
- ID: uuid.New().String(),
- Type: didCommServiceType,
- RecipientKeys: []string{didKey},
- RoutingKeys: routingKeys,
- ServiceEndpoint: serviceEndpoint,
+ ID: uuid.New().String(),
+ Type: didCommServiceType,
+ RecipientKeys: []string{didKey},
+ ServiceEndpoint: model.Endpoint{
+ URI: serviceEndpoint,
+ RoutingKeys: routingKeys,
+ },
}, nil
}
}
diff --git a/pkg/client/outofband/client_test.go b/pkg/client/outofband/client_test.go
index 7b6e5710f..7fdaf492b 100644
--- a/pkg/client/outofband/client_test.go
+++ b/pkg/client/outofband/client_test.go
@@ -17,6 +17,7 @@ import (
"github.com/google/uuid"
"github.com/stretchr/testify/require"
+ commonmodel "github.com/hyperledger/aries-framework-go/pkg/common/model"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/service"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/decorator"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/didexchange"
@@ -74,13 +75,15 @@ func TestCreateInvitation(t *testing.T) {
})
t.Run("includes the diddoc Service block returned by provider", func(t *testing.T) {
expected := &did.Service{
- ID: uuid.New().String(),
- Type: uuid.New().String(),
- Priority: 0,
- RecipientKeys: []string{uuid.New().String()},
- RoutingKeys: []string{uuid.New().String()},
- ServiceEndpoint: uuid.New().String(),
- Properties: nil,
+ ID: uuid.New().String(),
+ Type: uuid.New().String(),
+ Priority: 0,
+ RecipientKeys: []string{uuid.New().String()},
+ ServiceEndpoint: commonmodel.Endpoint{
+ URI: uuid.New().String(),
+ RoutingKeys: []string{uuid.New().String()},
+ },
+ Properties: nil,
}
c, err := New(withTestProvider())
require.NoError(t, err)
@@ -134,12 +137,18 @@ func TestCreateInvitation(t *testing.T) {
serviceType = vdr.DIDCommServiceType
}
- return &did.Service{ServiceEndpoint: expectedConn, Type: serviceType}, nil
+ return &did.Service{
+ ServiceEndpoint: commonmodel.Endpoint{
+ URI: expectedConn,
+ Accept: accept,
+ },
+ Type: serviceType,
+ }, nil
}
inv, err := c.CreateInvitation(nil, WithRouterConnections(expectedConn))
require.NoError(t, err)
- require.Equal(t, expectedConn, inv.Services[0].(*did.Service).ServiceEndpoint)
+ require.Equal(t, expectedConn, inv.Services[0].(*did.Service).ServiceEndpoint.URI)
})
t.Run("WithGoal", func(t *testing.T) {
c, err := New(withTestProvider())
@@ -155,13 +164,15 @@ func TestCreateInvitation(t *testing.T) {
c, err := New(withTestProvider())
require.NoError(t, err)
expected := &did.Service{
- ID: uuid.New().String(),
- Type: uuid.New().String(),
- Priority: 0,
- RecipientKeys: []string{uuid.New().String()},
- RoutingKeys: []string{uuid.New().String()},
- ServiceEndpoint: uuid.New().String(),
- Properties: nil,
+ ID: uuid.New().String(),
+ Type: uuid.New().String(),
+ Priority: 0,
+ RecipientKeys: []string{uuid.New().String()},
+ ServiceEndpoint: commonmodel.Endpoint{
+ URI: uuid.New().String(),
+ RoutingKeys: []string{uuid.New().String()},
+ },
+ Properties: nil,
}
inv, err := c.CreateInvitation([]interface{}{expected})
require.NoError(t, err)
@@ -182,13 +193,15 @@ func TestCreateInvitation(t *testing.T) {
require.NoError(t, err)
didRef := "did:example:234"
svc := &did.Service{
- ID: uuid.New().String(),
- Type: uuid.New().String(),
- Priority: 0,
- RecipientKeys: []string{uuid.New().String()},
- RoutingKeys: []string{uuid.New().String()},
- ServiceEndpoint: uuid.New().String(),
- Properties: nil,
+ ID: uuid.New().String(),
+ Type: uuid.New().String(),
+ Priority: 0,
+ RecipientKeys: []string{uuid.New().String()},
+ ServiceEndpoint: commonmodel.Endpoint{
+ URI: uuid.New().String(),
+ RoutingKeys: []string{uuid.New().String()},
+ },
+ Properties: nil,
}
inv, err := c.CreateInvitation([]interface{}{svc, didRef})
require.NoError(t, err)
diff --git a/pkg/common/model/endpoint.go b/pkg/common/model/endpoint.go
new file mode 100644
index 000000000..9916c154e
--- /dev/null
+++ b/pkg/common/model/endpoint.go
@@ -0,0 +1,17 @@
+/*
+Copyright SecureKey Technologies Inc. All Rights Reserved.
+
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package model
+
+// Endpoint contains endpoint specific content.
+type Endpoint struct {
+ // URI contains the endpoint URI.
+ URI string `json:"uri"`
+ // Accept contains the MediaType profiles accepted by this endpoint.
+ Accept []string `json:"accept,omitempty"`
+ // RoutingKeys contains the list of keys trusted as routing keys for the mediators/routers of this endpoint.
+ RoutingKeys []string `json:"routingKeys,omitempty"`
+}
diff --git a/pkg/controller/command/didexchange/command_test.go b/pkg/controller/command/didexchange/command_test.go
index e237cdc96..c8e60b305 100644
--- a/pkg/controller/command/didexchange/command_test.go
+++ b/pkg/controller/command/didexchange/command_test.go
@@ -21,6 +21,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/hyperledger/aries-framework-go/component/storageutil/mem"
+ "github.com/hyperledger/aries-framework-go/pkg/common/model"
"github.com/hyperledger/aries-framework-go/pkg/controller/command"
mockwebhook "github.com/hyperledger/aries-framework-go/pkg/controller/internal/mocks/webhook"
"github.com/hyperledger/aries-framework-go/pkg/controller/webnotifier"
@@ -988,8 +989,10 @@ func newPeerDID(t *testing.T) *did.Doc {
d, err := ctx.VDRegistry().Create(
peer.DIDMethod, &did.Doc{Service: []did.Service{{
- Type: vdr.DIDCommServiceType,
- ServiceEndpoint: "http://agent.example.com/didcomm",
+ Type: vdr.DIDCommServiceType,
+ ServiceEndpoint: model.Endpoint{
+ URI: "http://agent.example.com/didcomm",
+ },
}}, VerificationMethod: []did.VerificationMethod{getSigningKey()}},
)
require.NoError(t, err)
diff --git a/pkg/controller/command/messaging/command.go b/pkg/controller/command/messaging/command.go
index daff17189..1e5a7779a 100644
--- a/pkg/controller/command/messaging/command.go
+++ b/pkg/controller/command/messaging/command.go
@@ -15,6 +15,7 @@ import (
"github.com/hyperledger/aries-framework-go/pkg/client/messaging"
"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/controller/command"
"github.com/hyperledger/aries-framework-go/pkg/controller/internal/cmdutil"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/service"
@@ -187,9 +188,11 @@ func (o *Command) Send(rw io.Writer, req io.Reader) command.Error {
var destination *service.Destination
if request.ServiceEndpointDestination != nil {
destination = &service.Destination{
- RoutingKeys: request.ServiceEndpointDestination.RoutingKeys,
- ServiceEndpoint: request.ServiceEndpointDestination.ServiceEndpoint,
- RecipientKeys: request.ServiceEndpointDestination.RecipientKeys,
+ ServiceEndpoint: model.Endpoint{
+ URI: request.ServiceEndpointDestination.ServiceEndpoint,
+ RoutingKeys: request.ServiceEndpointDestination.RoutingKeys,
+ },
+ RecipientKeys: request.ServiceEndpointDestination.RecipientKeys,
}
}
diff --git a/pkg/controller/rest/didexchange/operation_test.go b/pkg/controller/rest/didexchange/operation_test.go
index 07d4d1cb1..b5c45feb8 100644
--- a/pkg/controller/rest/didexchange/operation_test.go
+++ b/pkg/controller/rest/didexchange/operation_test.go
@@ -24,6 +24,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/hyperledger/aries-framework-go/component/storageutil/mem"
+ "github.com/hyperledger/aries-framework-go/pkg/common/model"
"github.com/hyperledger/aries-framework-go/pkg/controller/command"
"github.com/hyperledger/aries-framework-go/pkg/controller/command/didexchange"
"github.com/hyperledger/aries-framework-go/pkg/controller/rest"
@@ -580,8 +581,10 @@ func newPeerDID(t *testing.T) *did.Doc {
d, err := ctx.VDRegistry().Create(
peer.DIDMethod, &did.Doc{Service: []did.Service{{
- Type: vdr.DIDCommServiceType,
- ServiceEndpoint: "http://agent.example.com/didcomm",
+ Type: vdr.DIDCommServiceType,
+ ServiceEndpoint: model.Endpoint{
+ URI: "http://agent.example.com/didcomm",
+ },
}}, VerificationMethod: []did.VerificationMethod{getSigningKey()}},
)
require.NoError(t, err)
diff --git a/pkg/didcomm/common/middleware/middleware.go b/pkg/didcomm/common/middleware/middleware.go
index f1ccc7e57..09d3e188e 100644
--- a/pkg/didcomm/common/middleware/middleware.go
+++ b/pkg/didcomm/common/middleware/middleware.go
@@ -15,6 +15,7 @@ import (
"github.com/google/uuid"
"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/crypto"
didcomm "github.com/hyperledger/aries-framework-go/pkg/didcomm/common/service"
"github.com/hyperledger/aries-framework-go/pkg/doc/did"
@@ -216,14 +217,16 @@ func (h *DIDCommMessageMiddleware) handleInboundInvitationAcceptance(senderDID,
// if we created an invitation with this DID, and have no connection, we create a connection.
rec = &connection.Record{
- ConnectionID: uuid.New().String(),
- MyDID: recipientDID,
- TheirDID: senderDID,
- InvitationID: inv.ID,
- State: connection.StateNameCompleted,
- Namespace: connection.MyNSPrefix,
- MediaTypeProfiles: h.mediaTypeProfiles,
- DIDCommVersion: didcomm.V2,
+ ConnectionID: uuid.New().String(),
+ MyDID: recipientDID,
+ TheirDID: senderDID,
+ InvitationID: inv.ID,
+ State: connection.StateNameCompleted,
+ Namespace: connection.MyNSPrefix,
+ ServiceEndPoint: model.Endpoint{
+ Accept: h.mediaTypeProfiles,
+ },
+ DIDCommVersion: didcomm.V2,
}
err = h.connStore.SaveConnectionRecord(rec)
diff --git a/pkg/didcomm/common/service/destination.go b/pkg/didcomm/common/service/destination.go
index c1d25e31f..41d1a1725 100644
--- a/pkg/didcomm/common/service/destination.go
+++ b/pkg/didcomm/common/service/destination.go
@@ -9,6 +9,7 @@ package service
import (
"fmt"
+ "github.com/hyperledger/aries-framework-go/pkg/common/model"
"github.com/hyperledger/aries-framework-go/pkg/doc/did"
vdrapi "github.com/hyperledger/aries-framework-go/pkg/framework/aries/api/vdr"
)
@@ -16,10 +17,8 @@ import (
// Destination provides the recipientKeys, routingKeys, and serviceEndpoint for an outbound message.
type Destination struct {
RecipientKeys []string
- ServiceEndpoint string
- RoutingKeys []string
+ ServiceEndpoint model.Endpoint
TransportReturnRoute string
- MediaTypeProfiles []string
DIDDoc *did.Doc
}
diff --git a/pkg/didcomm/common/service/destination_default.go b/pkg/didcomm/common/service/destination_default.go
index f6ba4b16a..026b701f0 100644
--- a/pkg/didcomm/common/service/destination_default.go
+++ b/pkg/didcomm/common/service/destination_default.go
@@ -12,12 +12,13 @@ import (
"fmt"
"strings"
+ "github.com/hyperledger/aries-framework-go/pkg/common/model"
diddoc "github.com/hyperledger/aries-framework-go/pkg/doc/did"
)
// CreateDestination makes a DIDComm Destination object from a DID Doc as per the DIDComm service conventions:
// https://github.com/hyperledger/aries-rfcs/blob/master/features/0067-didcomm-diddoc-conventions/README.md.
-//nolint:gocyclo
+//nolint:gocyclo,funlen
func CreateDestination(didDoc *diddoc.Doc) (*Destination, error) {
// try DIDComm V2 and use it if found, else use default DIDComm v1 bloc.
didCommService, ok := diddoc.LookupService(didDoc, didCommV2ServiceType)
@@ -42,8 +43,8 @@ func CreateDestination(didDoc *diddoc.Doc) (*Destination, error) {
didCommService.RecipientKeys = recKeys
// if Accept is missing, ensure DIDCommV2 is at least added for packer selection based on MediaTypeProfile.
- if len(didCommService.Accept) == 0 {
- didCommService.Accept = []string{defaultDIDCommV2Profile}
+ if len(didCommService.ServiceEndpoint.Accept) == 0 {
+ didCommService.ServiceEndpoint.Accept = []string{defaultDIDCommV2Profile}
}
} else {
didCommService, ok = diddoc.LookupService(didDoc, didCommServiceType)
@@ -51,8 +52,8 @@ func CreateDestination(didDoc *diddoc.Doc) (*Destination, error) {
return nil, fmt.Errorf("create destination: missing DID doc service")
}
- if didCommService.ServiceEndpoint == "" {
- return nil, fmt.Errorf("create destination: no service endpoint on didcomm service block in diddoc: %+v", didDoc)
+ if didCommService.ServiceEndpoint.URI == "" {
+ return nil, fmt.Errorf("create destination: no service endpoint URI on didcomm service block in diddoc: %+v", didDoc)
}
if len(didCommService.RecipientKeys) == 0 {
@@ -67,16 +68,18 @@ func CreateDestination(didDoc *diddoc.Doc) (*Destination, error) {
}
// if Accept is missing, ensure DIDCommV1 is at least added for packer selection based on MediaTypeProfile.
- if len(didCommService.Accept) == 0 {
- didCommService.Accept = []string{defaultDIDCommProfile}
+ if len(didCommService.ServiceEndpoint.Accept) == 0 {
+ didCommService.ServiceEndpoint.Accept = []string{defaultDIDCommProfile}
}
}
return &Destination{
- RecipientKeys: didCommService.RecipientKeys,
- ServiceEndpoint: didCommService.ServiceEndpoint,
- RoutingKeys: didCommService.RoutingKeys,
- MediaTypeProfiles: didCommService.Accept,
- DIDDoc: didDoc,
+ RecipientKeys: didCommService.RecipientKeys,
+ ServiceEndpoint: model.Endpoint{
+ URI: didCommService.ServiceEndpoint.URI,
+ RoutingKeys: didCommService.ServiceEndpoint.RoutingKeys,
+ Accept: didCommService.ServiceEndpoint.Accept,
+ },
+ DIDDoc: didDoc,
}, nil
}
diff --git a/pkg/didcomm/common/service/destination_test.go b/pkg/didcomm/common/service/destination_test.go
index 7f98738ae..bd34db391 100644
--- a/pkg/didcomm/common/service/destination_test.go
+++ b/pkg/didcomm/common/service/destination_test.go
@@ -17,6 +17,7 @@ import (
"github.com/btcsuite/btcutil/base58"
"github.com/stretchr/testify/require"
+ "github.com/hyperledger/aries-framework-go/pkg/common/model"
"github.com/hyperledger/aries-framework-go/pkg/doc/did"
mockdiddoc "github.com/hyperledger/aries-framework-go/pkg/mock/diddoc"
mockvdr "github.com/hyperledger/aries-framework-go/pkg/mock/vdr"
@@ -85,7 +86,7 @@ func TestGetDestinationFromDID(t *testing.T) {
t.Run("fails if the service endpoint is missing", func(t *testing.T) {
diddoc := createDIDDoc()
for i := range diddoc.Service {
- diddoc.Service[i].ServiceEndpoint = ""
+ diddoc.Service[i].ServiceEndpoint.URI = ""
}
vdr := &mockvdr.MockVDRegistry{ResolveValue: diddoc}
_, err := GetDestination(diddoc.ID, vdr)
@@ -117,8 +118,8 @@ func TestPrepareDestination(t *testing.T) {
dest, err := CreateDestination(doc)
require.NoError(t, err)
require.NotNil(t, dest)
- require.Equal(t, dest.ServiceEndpoint, "https://localhost:8090")
- require.Equal(t, doc.Service[0].RoutingKeys, dest.RoutingKeys)
+ require.Equal(t, dest.ServiceEndpoint.URI, "https://localhost:8090")
+ require.EqualValues(t, doc.Service[0].ServiceEndpoint.RoutingKeys, dest.ServiceEndpoint.RoutingKeys)
})
t.Run("error with destination having recipientKeys not did:keys", func(t *testing.T) {
@@ -182,11 +183,15 @@ func createDIDDocWithKey(pub string) *did.Doc {
}
services := []did.Service{
{
- ID: fmt.Sprintf(didServiceID, id, 1),
- Type: "did-communication",
- ServiceEndpoint: "http://localhost:58416",
- Priority: 0,
- RecipientKeys: []string{pubKeyID},
+ ID: fmt.Sprintf(didServiceID, id, 1),
+ Type: "did-communication",
+ ServiceEndpoint: model.Endpoint{
+ URI: "http://localhost:58416",
+ Accept: nil,
+ RoutingKeys: nil,
+ },
+ Priority: 0,
+ RecipientKeys: []string{pubKeyID},
},
}
createdTime := time.Now()
diff --git a/pkg/didcomm/dispatcher/outbound/outbound.go b/pkg/didcomm/dispatcher/outbound/outbound.go
index baea1d29e..06051a923 100644
--- a/pkg/didcomm/dispatcher/outbound/outbound.go
+++ b/pkg/didcomm/dispatcher/outbound/outbound.go
@@ -15,6 +15,7 @@ import (
"github.com/google/uuid"
"github.com/hyperledger/aries-framework-go/pkg/common/log"
+ commonmodel "github.com/hyperledger/aries-framework-go/pkg/common/model"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/middleware"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/model"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/service"
@@ -157,9 +158,9 @@ func (o *Dispatcher) SendToDID(msg interface{}, myDID, theirDID string) error {
"outboundDispatcher.SendToDID failed to get didcomm destination for theirDID [%s]: %w", theirDID, err)
}
- if len(connRec.MediaTypeProfiles) > 0 {
- dest.MediaTypeProfiles = make([]string, len(connRec.MediaTypeProfiles))
- copy(dest.MediaTypeProfiles, connRec.MediaTypeProfiles)
+ if len(connRec.ServiceEndPoint.Accept) > 0 {
+ dest.ServiceEndpoint.Accept = make([]string, len(connRec.ServiceEndPoint.Accept))
+ copy(dest.ServiceEndpoint.Accept, connRec.ServiceEndPoint.Accept)
}
mtp := o.mediaTypeProfile(dest)
@@ -206,13 +207,13 @@ func (o *Dispatcher) getOrCreateConnection(myDID, theirDID string, connectionVer
logger.Debugf("no connection record found for myDID=%s theirDID=%s, will create", myDID, theirDID)
newRecord := connection.Record{
- ConnectionID: uuid.New().String(),
- MyDID: myDID,
- TheirDID: theirDID,
- State: connection.StateNameCompleted,
- Namespace: connection.MyNSPrefix,
- MediaTypeProfiles: o.defaultMediaTypeProfiles(),
- DIDCommVersion: connectionVersion,
+ ConnectionID: uuid.New().String(),
+ MyDID: myDID,
+ TheirDID: theirDID,
+ State: connection.StateNameCompleted,
+ Namespace: connection.MyNSPrefix,
+ ServiceEndPoint: commonmodel.Endpoint{Accept: o.defaultMediaTypeProfiles()},
+ DIDCommVersion: connectionVersion,
}
err = o.connections.SaveConnectionRecord(&newRecord)
@@ -227,14 +228,14 @@ func (o *Dispatcher) getOrCreateConnection(myDID, theirDID string, connectionVer
func (o *Dispatcher) Send(msg interface{}, senderKey string, des *service.Destination) error { // nolint:funlen,gocyclo
// check if outbound accepts routing keys, else use recipient keys
keys := des.RecipientKeys
- if len(des.RoutingKeys) != 0 {
- keys = des.RoutingKeys
+ if len(des.ServiceEndpoint.RoutingKeys) != 0 {
+ keys = des.ServiceEndpoint.RoutingKeys
}
var outboundTransport transport.OutboundTransport
for _, v := range o.outboundTransports {
- if v.AcceptRecipient(keys) || v.Accept(des.ServiceEndpoint) {
+ if v.AcceptRecipient(keys) || v.Accept(des.ServiceEndpoint.URI) {
outboundTransport = v
break
}
@@ -293,7 +294,7 @@ func (o *Dispatcher) Send(msg interface{}, senderKey string, des *service.Destin
func (o *Dispatcher) Forward(msg interface{}, des *service.Destination) error {
for _, v := range o.outboundTransports {
if !v.AcceptRecipient(des.RecipientKeys) {
- if !v.Accept(des.ServiceEndpoint) {
+ if !v.Accept(des.ServiceEndpoint.URI) {
continue
}
}
@@ -311,7 +312,7 @@ func (o *Dispatcher) Forward(msg interface{}, des *service.Destination) error {
return nil
}
- return fmt.Errorf("outboundDispatcher.Forward: no transport found for serviceEndpoint: %s", des.ServiceEndpoint)
+ return fmt.Errorf("outboundDispatcher.Forward: no transport found for serviceEndpoint: %s", des.ServiceEndpoint.URI)
}
func (o *Dispatcher) createForwardMessage(msg []byte, des *service.Destination) ([]byte, error) {
@@ -341,7 +342,7 @@ func (o *Dispatcher) createForwardMessage(msg []byte, des *service.Destination)
senderKey = []byte(senderDIDKey)
}
- if len(des.RoutingKeys) == 0 {
+ if len(des.ServiceEndpoint.RoutingKeys) == 0 {
return msg, nil
}
@@ -363,7 +364,7 @@ func (o *Dispatcher) createForwardMessage(msg []byte, des *service.Destination)
MediaTypeProfile: mtProfile,
Message: req,
FromKey: senderKey,
- ToKeys: des.RoutingKeys,
+ ToKeys: des.ServiceEndpoint.RoutingKeys,
})
if err != nil {
return nil, fmt.Errorf("failed to pack forward msg: %w", err)
@@ -374,7 +375,7 @@ func (o *Dispatcher) createForwardMessage(msg []byte, des *service.Destination)
func (o *Dispatcher) addTransportRouteOptions(req []byte, des *service.Destination) ([]byte, error) {
// dont add transport route options for forward messages
- if len(des.RoutingKeys) != 0 {
+ if len(des.ServiceEndpoint.RoutingKeys) != 0 {
return req, nil
}
@@ -402,8 +403,8 @@ func (o *Dispatcher) addTransportRouteOptions(req []byte, des *service.Destinati
func (o *Dispatcher) mediaTypeProfile(des *service.Destination) string {
mt := ""
- if len(des.MediaTypeProfiles) > 0 {
- for _, mtp := range des.MediaTypeProfiles {
+ if len(des.ServiceEndpoint.Accept) > 0 {
+ for _, mtp := range des.ServiceEndpoint.Accept {
switch mtp {
case transport.MediaTypeV1PlaintextPayload, transport.MediaTypeRFC0019EncryptedEnvelope,
transport.MediaTypeAIP2RFC0019Profile, transport.MediaTypeProfileDIDCommAIP1:
diff --git a/pkg/didcomm/dispatcher/outbound/outbound_test.go b/pkg/didcomm/dispatcher/outbound/outbound_test.go
index 384d942d3..d8a45ebc0 100644
--- a/pkg/didcomm/dispatcher/outbound/outbound_test.go
+++ b/pkg/didcomm/dispatcher/outbound/outbound_test.go
@@ -15,6 +15,7 @@ import (
"github.com/google/uuid"
"github.com/stretchr/testify/require"
+ "github.com/hyperledger/aries-framework-go/pkg/common/model"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/middleware"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/service"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/decorator"
@@ -56,7 +57,9 @@ func TestOutboundDispatcher_Send(t *testing.T) {
mediaTypeProfiles: []string{transport.MediaTypeV1PlaintextPayload},
})
require.NoError(t, err)
- require.NoError(t, o.Send("data", mockdiddoc.MockDIDKey(t), &service.Destination{ServiceEndpoint: "url"}))
+ require.NoError(t, o.Send("data", mockdiddoc.MockDIDKey(t), &service.Destination{
+ ServiceEndpoint: model.Endpoint{URI: "url"},
+ }))
})
t.Run("test success", func(t *testing.T) {
@@ -73,9 +76,11 @@ func TestOutboundDispatcher_Send(t *testing.T) {
toDIDDoc := mockdiddoc.GetMockDIDDocWithDIDCommV2Bloc(t, "bob")
require.NoError(t, o.Send("data", fromDIDDoc.KeyAgreement[0].VerificationMethod.ID, &service.Destination{
- RecipientKeys: []string{toDIDDoc.KeyAgreement[0].VerificationMethod.ID},
- ServiceEndpoint: "url",
- MediaTypeProfiles: []string{transport.MediaTypeDIDCommV2Profile},
+ RecipientKeys: []string{toDIDDoc.KeyAgreement[0].VerificationMethod.ID},
+ ServiceEndpoint: model.Endpoint{
+ URI: "url",
+ Accept: []string{transport.MediaTypeDIDCommV2Profile},
+ },
}))
})
@@ -88,7 +93,9 @@ func TestOutboundDispatcher_Send(t *testing.T) {
mediaTypeProfiles: []string{transport.MediaTypeDIDCommV2Profile},
})
require.NoError(t, err)
- err = o.Send("data", mockdiddoc.MockDIDKey(t), &service.Destination{ServiceEndpoint: "url"})
+ err = o.Send("data", mockdiddoc.MockDIDKey(t), &service.Destination{
+ ServiceEndpoint: model.Endpoint{URI: "url"},
+ })
require.Error(t, err)
require.Contains(t, err.Error(), "outboundDispatcher.Send: no transport found for destination")
})
@@ -102,7 +109,9 @@ func TestOutboundDispatcher_Send(t *testing.T) {
mediaTypeProfiles: []string{transport.MediaTypeDIDCommV2Profile},
})
require.NoError(t, err)
- err = o.Send("data", mockdiddoc.MockDIDKey(t), &service.Destination{ServiceEndpoint: "url"})
+ err = o.Send("data", mockdiddoc.MockDIDKey(t), &service.Destination{
+ ServiceEndpoint: model.Endpoint{URI: "url"},
+ })
require.Error(t, err)
require.Contains(t, err.Error(), "pack error")
})
@@ -118,7 +127,8 @@ func TestOutboundDispatcher_Send(t *testing.T) {
mediaTypeProfiles: []string{transport.MediaTypeDIDCommV2Profile},
})
require.NoError(t, err)
- err = o.Send("data", mockdiddoc.MockDIDKey(t), &service.Destination{ServiceEndpoint: "url"})
+ err = o.Send("data", mockdiddoc.MockDIDKey(t),
+ &service.Destination{ServiceEndpoint: model.Endpoint{URI: "url"}})
require.Error(t, err)
require.Contains(t, err.Error(), "send error")
})
@@ -134,9 +144,11 @@ func TestOutboundDispatcher_Send(t *testing.T) {
require.NoError(t, err)
require.NoError(t, o.Send("data", mockdiddoc.MockDIDKey(t), &service.Destination{
- ServiceEndpoint: "url",
- RecipientKeys: []string{"abc"},
- RoutingKeys: []string{"xyz"},
+ ServiceEndpoint: model.Endpoint{
+ URI: "url",
+ RoutingKeys: []string{"xyz"},
+ },
+ RecipientKeys: []string{"abc"},
}))
})
@@ -155,9 +167,11 @@ func TestOutboundDispatcher_Send(t *testing.T) {
require.NoError(t, err)
require.NoError(t, o.Send("data", mockdiddoc.MockDIDKey(t), &service.Destination{
- ServiceEndpoint: "url",
- RecipientKeys: []string{"abc"},
- RoutingKeys: []string{"xyz"},
+ ServiceEndpoint: model.Endpoint{
+ URI: "url",
+ RoutingKeys: []string{"xyz"},
+ },
+ RecipientKeys: []string{"abc"},
}))
})
@@ -175,9 +189,11 @@ func TestOutboundDispatcher_Send(t *testing.T) {
require.NoError(t, err)
err = o.Send("data", mockdiddoc.MockDIDKey(t), &service.Destination{
- ServiceEndpoint: "url",
- RecipientKeys: []string{"abc"},
- RoutingKeys: []string{"xyz"},
+ ServiceEndpoint: model.Endpoint{
+ URI: "url",
+ RoutingKeys: []string{"xyz"},
+ },
+ RecipientKeys: []string{"abc"},
})
require.EqualError(t, err, "outboundDispatcher.Send: failed to create forward msg: failed Create "+
"and export Encryption Key: create and export key error")
@@ -194,9 +210,11 @@ func TestOutboundDispatcher_Send(t *testing.T) {
require.NoError(t, err)
_, err = o.createForwardMessage(createPackedMsgForForward(t), &service.Destination{
- ServiceEndpoint: "url",
- RecipientKeys: []string{"abc"},
- RoutingKeys: []string{"xyz"},
+ ServiceEndpoint: model.Endpoint{
+ URI: "url",
+ RoutingKeys: []string{"xyz"},
+ },
+ RecipientKeys: []string{"abc"},
})
require.Error(t, err)
require.Contains(t, err.Error(), "pack forward msg")
@@ -536,7 +554,8 @@ func TestOutboundDispatcherTransportReturnRoute(t *testing.T) {
})
require.NoError(t, err)
- require.NoError(t, o.Send(req, mockdiddoc.MockDIDKey(t), &service.Destination{ServiceEndpoint: "url"}))
+ require.NoError(t, o.Send(req, mockdiddoc.MockDIDKey(t),
+ &service.Destination{ServiceEndpoint: model.Endpoint{URI: "url"}}))
})
t.Run("transport route option - value set thread", func(t *testing.T) {
@@ -570,7 +589,8 @@ func TestOutboundDispatcherTransportReturnRoute(t *testing.T) {
})
require.NoError(t, err)
- require.NoError(t, o.Send(req, mockdiddoc.MockDIDKey(t), &service.Destination{ServiceEndpoint: "url"}))
+ require.NoError(t, o.Send(req, mockdiddoc.MockDIDKey(t),
+ &service.Destination{ServiceEndpoint: model.Endpoint{URI: "url"}}))
})
t.Run("transport route option - no value set", func(t *testing.T) {
@@ -596,7 +616,8 @@ func TestOutboundDispatcherTransportReturnRoute(t *testing.T) {
})
require.NoError(t, err)
- require.NoError(t, o.Send(req, mockdiddoc.MockDIDKey(t), &service.Destination{ServiceEndpoint: "url"}))
+ require.NoError(t, o.Send(req, mockdiddoc.MockDIDKey(t),
+ &service.Destination{ServiceEndpoint: model.Endpoint{URI: "url"}}))
})
t.Run("transport route option - forward message", func(t *testing.T) {
@@ -612,7 +633,8 @@ func TestOutboundDispatcherTransportReturnRoute(t *testing.T) {
testData := []byte("testData")
- data, err := o.addTransportRouteOptions(testData, &service.Destination{RoutingKeys: []string{"abc"}})
+ data, err := o.addTransportRouteOptions(testData,
+ &service.Destination{ServiceEndpoint: model.Endpoint{RoutingKeys: []string{"abc"}}})
require.NoError(t, err)
require.Equal(t, testData, data)
})
@@ -628,7 +650,7 @@ func TestOutboundDispatcher_Forward(t *testing.T) {
mediaTypeProfiles: []string{transport.MediaTypeDIDCommV2Profile},
})
require.NoError(t, err)
- require.NoError(t, o.Forward("data", &service.Destination{ServiceEndpoint: "url"}))
+ require.NoError(t, o.Forward("data", &service.Destination{ServiceEndpoint: model.Endpoint{URI: "url"}}))
})
t.Run("test forward - no outbound transport found", func(t *testing.T) {
@@ -640,7 +662,7 @@ func TestOutboundDispatcher_Forward(t *testing.T) {
mediaTypeProfiles: []string{transport.MediaTypeDIDCommV2Profile},
})
require.NoError(t, err)
- err = o.Forward("data", &service.Destination{ServiceEndpoint: "url"})
+ err = o.Forward("data", &service.Destination{ServiceEndpoint: model.Endpoint{URI: "url"}})
require.Error(t, err)
require.Contains(t, err.Error(), "outboundDispatcher.Forward: no transport found for serviceEndpoint: url")
})
@@ -656,7 +678,7 @@ func TestOutboundDispatcher_Forward(t *testing.T) {
mediaTypeProfiles: []string{transport.MediaTypeDIDCommV2Profile},
})
require.NoError(t, err)
- err = o.Forward("data", &service.Destination{ServiceEndpoint: "url"})
+ err = o.Forward("data", &service.Destination{ServiceEndpoint: model.Endpoint{URI: "url"}})
require.Error(t, err)
require.Contains(t, err.Error(), "send error")
})
diff --git a/pkg/didcomm/protocol/didexchange/service.go b/pkg/didcomm/protocol/didexchange/service.go
index c8b42ba2a..d8b924b87 100644
--- a/pkg/didcomm/protocol/didexchange/service.go
+++ b/pkg/didcomm/protocol/didexchange/service.go
@@ -15,6 +15,7 @@ import (
"github.com/google/uuid"
"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/crypto"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/service"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/dispatcher"
@@ -737,17 +738,19 @@ func (s *Service) oobInvitationMsgRecord(msg service.DIDCommMsg) (*connection.Re
}
connRecord := &connection.Record{
- ConnectionID: generateRandomID(),
- ThreadID: thID,
- ParentThreadID: oobInvitation.ThreadID,
- State: stateNameNull,
- InvitationID: oobInvitation.ID,
- ServiceEndPoint: svc.ServiceEndpoint, // TODO: service endpoint should be 'theirs' not 'mine'.
- RecipientKeys: svc.RecipientKeys, // TODO: recipient keys should be 'theirs' not 'mine'.
- TheirLabel: oobInvitation.TheirLabel,
- Namespace: findNamespace(msg.Type()),
- MediaTypeProfiles: svc.Accept,
- DIDCommVersion: service.V1,
+ ConnectionID: generateRandomID(),
+ ThreadID: thID,
+ ParentThreadID: oobInvitation.ThreadID,
+ State: stateNameNull,
+ InvitationID: oobInvitation.ID,
+ ServiceEndPoint: model.Endpoint{
+ URI: svc.ServiceEndpoint.URI, // TODO: service endpoint should be 'theirs' not 'mine'.
+ Accept: svc.ServiceEndpoint.Accept,
+ },
+ RecipientKeys: svc.RecipientKeys, // TODO: recipient keys should be 'theirs' not 'mine'.
+ TheirLabel: oobInvitation.TheirLabel,
+ Namespace: findNamespace(msg.Type()),
+ DIDCommVersion: service.V1,
}
publicDID, ok := oobInvitation.Target.(string)
@@ -782,16 +785,20 @@ func (s *Service) invitationMsgRecord(msg service.DIDCommMsg) (*connection.Recor
}
connRecord := &connection.Record{
- ConnectionID: generateRandomID(),
- ThreadID: thID,
- State: stateNameNull,
- InvitationID: invitation.ID,
- InvitationDID: invitation.DID,
- ServiceEndPoint: invitation.ServiceEndpoint,
- RecipientKeys: []string{recKey},
- TheirLabel: invitation.Label,
- Namespace: findNamespace(msg.Type()),
- DIDCommVersion: service.V1,
+ ConnectionID: generateRandomID(),
+ ThreadID: thID,
+ State: stateNameNull,
+ InvitationID: invitation.ID,
+ InvitationDID: invitation.DID,
+ ServiceEndPoint: model.Endpoint{
+ URI: invitation.ServiceEndpoint,
+ Accept: nil,
+ RoutingKeys: nil,
+ },
+ RecipientKeys: []string{recKey},
+ TheirLabel: invitation.Label,
+ Namespace: findNamespace(msg.Type()),
+ DIDCommVersion: service.V1,
}
if err := s.connectionRecorder.SaveConnectionRecord(connRecord); err != nil {
diff --git a/pkg/didcomm/protocol/didexchange/service_test.go b/pkg/didcomm/protocol/didexchange/service_test.go
index 57aad6b0c..d0ed8ae4c 100644
--- a/pkg/didcomm/protocol/didexchange/service_test.go
+++ b/pkg/didcomm/protocol/didexchange/service_test.go
@@ -20,6 +20,7 @@ import (
"github.com/google/uuid"
"github.com/stretchr/testify/require"
+ commonmodel "github.com/hyperledger/aries-framework-go/pkg/common/model"
"github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/model"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/service"
@@ -405,7 +406,7 @@ func TestService_Handle_Invitee(t *testing.T) {
require.Equal(t, (&requested{}).Name(), connRecord.State)
require.Equal(t, invitation.ID, connRecord.InvitationID)
require.Equal(t, invitation.RecipientKeys, connRecord.RecipientKeys)
- require.Equal(t, invitation.ServiceEndpoint, connRecord.ServiceEndPoint)
+ require.Equal(t, invitation.ServiceEndpoint, connRecord.ServiceEndPoint.URI)
didKey, err := ctx.getVerKey(invitation.ID)
require.NoError(t, err)
@@ -693,7 +694,7 @@ func TestCreateConnection(t *testing.T) {
TheirLabel: uuid.New().String(),
TheirDID: theirDID.ID,
MyDID: newPeerDID(t, k).ID,
- ServiceEndPoint: "http://example.com",
+ ServiceEndPoint: commonmodel.Endpoint{URI: "http://example.com"},
RecipientKeys: []string{"testkeys"},
InvitationID: uuid.New().String(),
Namespace: myNSPrefix,
@@ -2182,7 +2183,7 @@ func TestRespondTo(t *testing.T) {
ID: uuid.New().String(),
Type: "did-communication",
RecipientKeys: []string{"did:key:1234567"},
- ServiceEndpoint: "http://example.com",
+ ServiceEndpoint: commonmodel.Endpoint{URI: "http://example.com"},
}), nil)
require.NoError(t, err)
require.NotEmpty(t, connID)
@@ -2323,7 +2324,7 @@ func newPeerDID(t *testing.T, k kms.KeyManager) *did.Doc {
Type: "did-communication",
Priority: 0,
RecipientKeys: []string{base58.Encode(pubKey)},
- ServiceEndpoint: "http://example.com",
+ ServiceEndpoint: commonmodel.Endpoint{URI: "http://example.com"},
}}),
)
require.NoError(t, err)
diff --git a/pkg/didcomm/protocol/didexchange/states.go b/pkg/didcomm/protocol/didexchange/states.go
index 4ee46a23f..9d1920c66 100644
--- a/pkg/didcomm/protocol/didexchange/states.go
+++ b/pkg/didcomm/protocol/didexchange/states.go
@@ -17,6 +17,7 @@ import (
"github.com/google/uuid"
"github.com/mitchellh/mapstructure"
+ "github.com/hyperledger/aries-framework-go/pkg/common/model"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/service"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/decorator"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/mediator"
@@ -323,10 +324,8 @@ func (ctx *context) handleInboundOOBInvitation(oobInv *OOBInvitation, thid strin
}
dest := &service.Destination{
- RecipientKeys: svc.RecipientKeys,
- ServiceEndpoint: svc.ServiceEndpoint,
- RoutingKeys: svc.RoutingKeys,
- MediaTypeProfiles: svc.Accept,
+ RecipientKeys: svc.RecipientKeys,
+ ServiceEndpoint: svc.ServiceEndpoint,
}
connRec.ThreadID = thid
@@ -363,7 +362,7 @@ func (ctx *context) createInvitedRequest(destination *service.Destination, label
// get did document to use in exchange request
myDIDDoc, err := ctx.getMyDIDDoc(getPublicDID(options), getRouterConnections(options),
- serviceTypeByMediaProfile(destination.MediaTypeProfiles))
+ serviceTypeByMediaProfile(destination.ServiceEndpoint.Accept))
if err != nil {
return nil, nil, err
}
@@ -449,7 +448,7 @@ func (ctx *context) handleInboundRequest(request *Request, options *options,
if len(requestDidDoc.Service) > 0 {
serviceType = requestDidDoc.Service[0].Type
} else {
- serviceType = serviceTypeByMediaProfile(destination.MediaTypeProfiles)
+ serviceType = serviceTypeByMediaProfile(destination.ServiceEndpoint.Accept)
}
responseDidDoc, err := ctx.getMyDIDDoc(myDID, getRouterConnections(options), serviceType)
@@ -489,8 +488,8 @@ func (ctx *context) handleInboundRequest(request *Request, options *options,
connRec.TheirDID = request.DID
connRec.TheirLabel = request.Label
- if len(destination.MediaTypeProfiles) > 0 {
- connRec.MediaTypeProfiles = destination.MediaTypeProfiles
+ if len(destination.ServiceEndpoint.Accept) > 0 {
+ connRec.ServiceEndPoint.Accept = destination.ServiceEndpoint.Accept
}
// send exchange response
@@ -630,10 +629,12 @@ func (ctx *context) getDestination(invitation *Invitation) (*service.Destination
}
return &service.Destination{
- RecipientKeys: invitation.RecipientKeys,
- ServiceEndpoint: invitation.ServiceEndpoint,
- RoutingKeys: invitation.RoutingKeys,
- MediaTypeProfiles: ctx.mediaTypeProfiles,
+ RecipientKeys: invitation.RecipientKeys,
+ ServiceEndpoint: model.Endpoint{
+ URI: invitation.ServiceEndpoint,
+ Accept: ctx.mediaTypeProfiles,
+ RoutingKeys: invitation.RoutingKeys,
+ },
}, nil
}
@@ -669,7 +670,10 @@ func (ctx *context) getMyDIDDoc(pubDID string, routerConnections []string, servi
return nil, fmt.Errorf("did doc - fetch router config: %w", err)
}
- services = append(services, did.Service{ServiceEndpoint: serviceEndpoint, RoutingKeys: routingKeys})
+ services = append(services, did.Service{ServiceEndpoint: model.Endpoint{
+ URI: serviceEndpoint,
+ RoutingKeys: routingKeys,
+ }})
}
if len(services) == 0 {
@@ -1027,7 +1031,7 @@ func (ctx *context) getServiceBlock(i *OOBInvitation) (*did.Service, error) {
// updating Accept header requires a cloned service block to avoid Data Race errors.
// RFC0587: In case the accept property is set in both the DID service block and the out-of-band message,
// the out-of-band property takes precedence.
- block.Accept = i.MediaTypeProfiles
+ block.ServiceEndpoint.Accept = i.MediaTypeProfiles
}
logger.Debugf("extracted service block=%+v", block)
diff --git a/pkg/didcomm/protocol/didexchange/states_test.go b/pkg/didcomm/protocol/didexchange/states_test.go
index a8e0e23d2..f70fb697a 100644
--- a/pkg/didcomm/protocol/didexchange/states_test.go
+++ b/pkg/didcomm/protocol/didexchange/states_test.go
@@ -17,6 +17,7 @@ import (
"github.com/google/uuid"
"github.com/stretchr/testify/require"
+ commonmodel "github.com/hyperledger/aries-framework-go/pkg/common/model"
"github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/model"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/service"
@@ -399,7 +400,7 @@ func TestRequestedState_Execute(t *testing.T) {
Type: didServiceType,
Priority: 0,
RecipientKeys: []string{"key"},
- ServiceEndpoint: "http://test.com",
+ ServiceEndpoint: commonmodel.Endpoint{URI: "http://test.com"},
},
}),
connRecord: &connection.Record{},
@@ -452,7 +453,7 @@ func TestRequestedState_Execute(t *testing.T) {
Type: didServiceType,
Priority: 0,
RecipientKeys: []string{"key"},
- ServiceEndpoint: "http://test.com",
+ ServiceEndpoint: commonmodel.Endpoint{URI: "http://test.com"},
},
}),
connRecord: &connection.Record{},
@@ -564,7 +565,7 @@ func TestRequestedState_Execute(t *testing.T) {
doc.Service = []diddoc.Service{{
Type: didServiceType,
- ServiceEndpoint: "http://test.com",
+ ServiceEndpoint: commonmodel.Endpoint{URI: "http://test.com"},
RecipientKeys: []string{expected},
}}
tc.ctx.vdRegistry = &mockvdr.MockVDRegistry{
@@ -638,8 +639,8 @@ func TestRequestedState_Execute(t *testing.T) {
options ...vdrapi.DIDMethodOption) (*diddoc.DocResolution, error) {
created = true
- require.Equal(t, expected.Keys(), didDoc.Service[0].RoutingKeys)
- require.Equal(t, expected.Endpoint(), didDoc.Service[0].ServiceEndpoint)
+ require.Equal(t, expected.Keys(), didDoc.Service[0].ServiceEndpoint.RoutingKeys)
+ require.Equal(t, expected.Endpoint(), didDoc.Service[0].ServiceEndpoint.URI)
return &diddoc.DocResolution{DIDDocument: docResolution}, nil
},
ResolveValue: docResolution,
@@ -700,12 +701,14 @@ func TestRequestedState_Execute(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
myDoc := createDIDDoc(t, tc.ctx)
myDoc.Service = []diddoc.Service{{
- ID: uuid.New().String(),
- Type: "invalid",
- Priority: 0,
- RecipientKeys: nil,
- RoutingKeys: nil,
- ServiceEndpoint: "",
+ ID: uuid.New().String(),
+ Type: "invalid",
+ Priority: 0,
+ RecipientKeys: nil,
+ ServiceEndpoint: commonmodel.Endpoint{
+ URI: "",
+ RoutingKeys: nil,
+ },
}}
tc.ctx.vdRegistry = &mockvdr.MockVDRegistry{CreateValue: myDoc}
_, _, _, err = (&requested{}).ExecuteInbound(&stateMachineMsg{
@@ -748,12 +751,14 @@ func TestRequestedState_Execute(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
myDoc := createDIDDoc(t, tc.ctx)
myDoc.Service = []diddoc.Service{{
- ID: uuid.New().String(),
- Type: "invalid",
- Priority: 0,
- RecipientKeys: nil,
- RoutingKeys: nil,
- ServiceEndpoint: "",
+ ID: uuid.New().String(),
+ Type: "invalid",
+ Priority: 0,
+ RecipientKeys: nil,
+ ServiceEndpoint: commonmodel.Endpoint{
+ URI: "",
+ RoutingKeys: nil,
+ },
}}
tc.ctx.vdRegistry = &mockvdr.MockVDRegistry{CreateValue: myDoc}
_, _, _, err = (&requested{}).ExecuteInbound(&stateMachineMsg{
@@ -767,7 +772,7 @@ func TestRequestedState_Execute(t *testing.T) {
Type: didServiceType,
Priority: 0,
RecipientKeys: []string{"key"},
- ServiceEndpoint: "http://test.com",
+ ServiceEndpoint: commonmodel.Endpoint{URI: "http://test.com"},
},
}),
connRecord: &connection.Record{},
@@ -909,12 +914,14 @@ func TestRespondedState_Execute(t *testing.T) {
ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, mtp)
myDoc := createDIDDoc(t, ctx)
myDoc.Service = []diddoc.Service{{
- ID: uuid.New().String(),
- Type: "invalid",
- Priority: 0,
- RecipientKeys: nil,
- RoutingKeys: nil,
- ServiceEndpoint: "",
+ ID: uuid.New().String(),
+ Type: "invalid",
+ Priority: 0,
+ RecipientKeys: nil,
+ ServiceEndpoint: commonmodel.Endpoint{
+ URI: "",
+ RoutingKeys: nil,
+ },
}}
ctx.vdRegistry = &mockvdr.MockVDRegistry{CreateValue: myDoc}
_, _, _, err := (&responded{}).ExecuteInbound(&stateMachineMsg{
@@ -2185,12 +2192,14 @@ func createDIDDocWithKey(verDIDKey, encDIDKey, mediaTypeProfile string) *diddoc.
services := []diddoc.Service{
{
- ID: fmt.Sprintf(didServiceID, id, 1),
- Type: didCommService,
- ServiceEndpoint: "http://localhost:58416",
- Priority: 0,
- RecipientKeys: []string{recKey},
- Accept: []string{mediaTypeProfile},
+ ID: fmt.Sprintf(didServiceID, id, 1),
+ Type: didCommService,
+ ServiceEndpoint: commonmodel.Endpoint{
+ URI: "http://localhost:58416",
+ Accept: []string{mediaTypeProfile},
+ },
+ Priority: 0,
+ RecipientKeys: []string{recKey},
},
}
createdTime := time.Now()
@@ -2360,8 +2369,8 @@ func newDidExchangeInvite(publicDID string, svc *diddoc.Service) *Invitation {
if svc != nil {
i.RecipientKeys = svc.RecipientKeys
- i.ServiceEndpoint = svc.ServiceEndpoint
- i.RoutingKeys = svc.RoutingKeys
+ i.ServiceEndpoint = svc.ServiceEndpoint.URI
+ i.RoutingKeys = svc.ServiceEndpoint.RoutingKeys
}
return i
@@ -2380,11 +2389,13 @@ func newOOBInvite(target interface{}) *OOBInvitation {
func newServiceBlock(recKeys, routingKeys []string, didCommServiceVType string) *diddoc.Service {
return &diddoc.Service{
- ID: uuid.New().String(),
- Type: didCommServiceVType,
- RecipientKeys: recKeys,
- RoutingKeys: routingKeys,
- ServiceEndpoint: "http://test.com",
+ ID: uuid.New().String(),
+ Type: didCommServiceVType,
+ RecipientKeys: recKeys,
+ ServiceEndpoint: commonmodel.Endpoint{
+ URI: "http://test.com",
+ RoutingKeys: routingKeys,
+ },
}
}
diff --git a/pkg/didcomm/protocol/introduce/models.go b/pkg/didcomm/protocol/introduce/models.go
index af024f858..f4649a95c 100644
--- a/pkg/didcomm/protocol/introduce/models.go
+++ b/pkg/didcomm/protocol/introduce/models.go
@@ -17,7 +17,7 @@ type Proposal struct {
Thread *decorator.Thread `json:"~thread,omitempty"`
Timing *decorator.Timing `json:"~timing,omitempty"`
Goal string `json:"goal,omitempty"`
- GoalCode string `json:"goal-code,omitempty"`
+ GoalCode string `json:"goal_code,omitempty"`
}
// To introducee descriptor keeps information about the introduction
diff --git a/pkg/didcomm/protocol/issuecredential/params_test.go b/pkg/didcomm/protocol/issuecredential/params_test.go
index 8ed35e651..3e2005ce2 100644
--- a/pkg/didcomm/protocol/issuecredential/params_test.go
+++ b/pkg/didcomm/protocol/issuecredential/params_test.go
@@ -18,7 +18,7 @@ import (
const (
commentText = "this is a comment"
- goalCodeText = "goal-code"
+ goalCodeText = "goal_code"
messageIDText = "message-id-123"
)
@@ -47,7 +47,7 @@ func previewCredV3(t *testing.T) map[string]interface{} {
Type: CredentialPreviewMsgTypeV3,
ID: "bar-baz-qux",
Body: IssueCredentialV3Body{
- GoalCode: "goal-code",
+ GoalCode: "goal_code",
ReplacementID: "blah-id",
Comment: commentText,
},
diff --git a/pkg/didcomm/protocol/outofband/service_test.go b/pkg/didcomm/protocol/outofband/service_test.go
index 3bd87d9fe..3e2de7ddd 100644
--- a/pkg/didcomm/protocol/outofband/service_test.go
+++ b/pkg/didcomm/protocol/outofband/service_test.go
@@ -17,6 +17,7 @@ import (
"github.com/google/uuid"
"github.com/stretchr/testify/require"
+ commonmodel "github.com/hyperledger/aries-framework-go/pkg/common/model"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/model"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/service"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/decorator"
@@ -977,12 +978,14 @@ func TestChooseTarget(t *testing.T) {
})
t.Run("chooses a did service entry", func(t *testing.T) {
expected := &did.Service{
- ID: uuid.New().String(),
- Type: "did-communication",
- Priority: 0,
- RecipientKeys: []string{"my ver key"},
- RoutingKeys: []string{"my routing key"},
- ServiceEndpoint: "my service endpoint",
+ ID: uuid.New().String(),
+ Type: "did-communication",
+ Priority: 0,
+ RecipientKeys: []string{"my ver key"},
+ ServiceEndpoint: commonmodel.Endpoint{
+ URI: "my service endpoint",
+ RoutingKeys: []string{"my routing key"},
+ },
}
result, err := chooseTarget([]interface{}{expected})
require.NoError(t, err)
@@ -990,12 +993,14 @@ func TestChooseTarget(t *testing.T) {
})
t.Run("chooses a map-type service", func(t *testing.T) {
expected := map[string]interface{}{
- "id": uuid.New().String(),
- "type": "did-communication",
- "priority": uint(0),
- "recipientKeys": []string{"my ver key"},
- "routingKeys": []string{"my routing key"},
- "serviceEndpoint": "my service endpoint",
+ "id": uuid.New().String(),
+ "type": "did-communication",
+ "priority": uint(0),
+ "recipientKeys": []string{"my ver key"},
+ "serviceEndpoint": commonmodel.Endpoint{
+ URI: "my service endpoint",
+ RoutingKeys: []string{"my routing key"},
+ },
}
svc, err := chooseTarget([]interface{}{expected})
require.NoError(t, err)
@@ -1005,7 +1010,6 @@ func TestChooseTarget(t *testing.T) {
require.Equal(t, expected["type"], result.Type)
require.Equal(t, expected["priority"], result.Priority)
require.Equal(t, expected["recipientKeys"], result.RecipientKeys)
- require.Equal(t, expected["routingKeys"], result.RoutingKeys)
require.Equal(t, expected["serviceEndpoint"], result.ServiceEndpoint)
})
t.Run("fails if not services are specified", func(t *testing.T) {
diff --git a/pkg/didcomm/protocol/outofbandv2/models.go b/pkg/didcomm/protocol/outofbandv2/models.go
index eebd37174..02b3b007f 100644
--- a/pkg/didcomm/protocol/outofbandv2/models.go
+++ b/pkg/didcomm/protocol/outofbandv2/models.go
@@ -21,6 +21,6 @@ type Invitation struct {
// InvitationBody contains invitation's goal and accept headers.
type InvitationBody struct {
Goal string `json:"goal,omitempty"`
- GoalCode string `json:"goal-code,omitempty"`
+ GoalCode string `json:"goal_code,omitempty"`
Accept []string `json:"accept,omitempty"`
}
diff --git a/pkg/didcomm/protocol/outofbandv2/service.go b/pkg/didcomm/protocol/outofbandv2/service.go
index 77173b392..a8feb21f2 100644
--- a/pkg/didcomm/protocol/outofbandv2/service.go
+++ b/pkg/didcomm/protocol/outofbandv2/service.go
@@ -16,6 +16,7 @@ import (
gojose "github.com/square/go-jose/v3"
"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/crypto"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/service"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/dispatcher"
@@ -267,10 +268,13 @@ func (s *Service) AcceptInvitation(i *Invitation, opts ...AcceptOption) (string,
}
services = append(services, did.Service{
- ServiceEndpoint: serviceEndpoint,
- RecipientKeys: []string{recKey},
- RoutingKeys: routingKeys,
- Type: vdrapi.DIDCommV2ServiceType,
+ ServiceEndpoint: model.Endpoint{
+ URI: serviceEndpoint,
+ Accept: s.myMediaTypeProfiles,
+ RoutingKeys: routingKeys,
+ },
+ RecipientKeys: []string{recKey},
+ Type: vdrapi.DIDCommV2ServiceType,
})
}
@@ -340,12 +344,10 @@ func (s *Service) AcceptInvitation(i *Invitation, opts ...AcceptOption) (string,
InvitationID: i.ID,
ServiceEndPoint: destination.ServiceEndpoint,
RecipientKeys: destination.RecipientKeys,
- RoutingKeys: destination.RoutingKeys,
TheirLabel: i.Label,
TheirDID: i.From,
MyDID: myDID.DIDDocument.ID,
Namespace: connection.MyNSPrefix,
- MediaTypeProfiles: s.myMediaTypeProfiles,
Implicit: true,
InvitationDID: myDID.DIDDocument.ID,
DIDCommVersion: service.V2,
diff --git a/pkg/didcomm/protocol/outofbandv2/service_test.go b/pkg/didcomm/protocol/outofbandv2/service_test.go
index 0b9854489..e74118948 100644
--- a/pkg/didcomm/protocol/outofbandv2/service_test.go
+++ b/pkg/didcomm/protocol/outofbandv2/service_test.go
@@ -280,8 +280,8 @@ func TestAcceptInvitation(t *testing.T) {
docSvc, ok := did.LookupService(createdDoc, vdrapi.DIDCommV2ServiceType)
require.True(t, ok)
- require.Len(t, docSvc.RoutingKeys, 1)
- require.Equal(t, testKey, docSvc.RoutingKeys[0])
+ require.Len(t, docSvc.ServiceEndpoint.RoutingKeys, 1)
+ require.Equal(t, testKey, docSvc.ServiceEndpoint.RoutingKeys[0])
})
t.Run("error fetching mediator config", func(t *testing.T) {
diff --git a/pkg/didcomm/transport/http/outbound.go b/pkg/didcomm/transport/http/outbound.go
index c5b538895..ffd48cd1e 100644
--- a/pkg/didcomm/transport/http/outbound.go
+++ b/pkg/didcomm/transport/http/outbound.go
@@ -92,7 +92,7 @@ func (cs *OutboundHTTPClient) Start(prov transport.Provider) error {
// Send sends a2a exchange data via HTTP (client side).
func (cs *OutboundHTTPClient) Send(data []byte, destination *service.Destination) (string, error) {
- resp, err := cs.client.Post(destination.ServiceEndpoint, commContentType, bytes.NewBuffer(data))
+ resp, err := cs.client.Post(destination.ServiceEndpoint.URI, commContentType, bytes.NewBuffer(data))
if err != nil {
logger.Errorf("posting DID envelope to agent failed [%s, %v]", destination.ServiceEndpoint, err)
return "", err
diff --git a/pkg/didcomm/transport/http/outbound_test.go b/pkg/didcomm/transport/http/outbound_test.go
index 3f043529d..b211dbee0 100644
--- a/pkg/didcomm/transport/http/outbound_test.go
+++ b/pkg/didcomm/transport/http/outbound_test.go
@@ -14,6 +14,7 @@ import (
"github.com/stretchr/testify/require"
+ "github.com/hyperledger/aries-framework-go/pkg/common/model"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/service"
)
@@ -101,6 +102,6 @@ func TestOutboundHTTPTransport(t *testing.T) {
func prepareDestination(endPoint string) *service.Destination {
return &service.Destination{
- ServiceEndpoint: endPoint,
+ ServiceEndpoint: model.Endpoint{URI: endPoint},
}
}
diff --git a/pkg/didcomm/transport/ws/outbound.go b/pkg/didcomm/transport/ws/outbound.go
index fd7eeac20..c0a5b8b80 100644
--- a/pkg/didcomm/transport/ws/outbound.go
+++ b/pkg/didcomm/transport/ws/outbound.go
@@ -92,8 +92,8 @@ func (cs *OutboundClient) getConnection(destination *service.Destination) (*webs
// get the connection for the routing or recipient keys
keys := destination.RecipientKeys
- if len(destination.RoutingKeys) != 0 {
- keys = destination.RoutingKeys
+ if len(destination.ServiceEndpoint.RoutingKeys) != 0 {
+ keys = destination.ServiceEndpoint.RoutingKeys
}
for _, v := range keys {
@@ -112,7 +112,7 @@ func (cs *OutboundClient) getConnection(destination *service.Destination) (*webs
var err error
- conn, _, err = websocket.Dial(context.Background(), destination.ServiceEndpoint, nil)
+ conn, _, err = websocket.Dial(context.Background(), destination.ServiceEndpoint.URI, nil)
if err != nil {
return nil, cleanup, fmt.Errorf("websocket client : %w", err)
}
diff --git a/pkg/didcomm/transport/ws/outbound_test.go b/pkg/didcomm/transport/ws/outbound_test.go
index 3a0ebeb55..499c6ddd5 100644
--- a/pkg/didcomm/transport/ws/outbound_test.go
+++ b/pkg/didcomm/transport/ws/outbound_test.go
@@ -126,7 +126,7 @@ func TestClient(t *testing.T) {
addr := startWebSocketServer(t, echo)
des := prepareDestinationWithTransport("ws://"+addr, decorator.TransportReturnRouteAll, recKey)
- des.RoutingKeys = routingKeys
+ des.ServiceEndpoint.RoutingKeys = routingKeys
data := "didcomm-message"
resp, err := outbound.Send([]byte(data), des)
diff --git a/pkg/didcomm/transport/ws/support_test.go b/pkg/didcomm/transport/ws/support_test.go
index 4f66f54ac..d6a44036e 100644
--- a/pkg/didcomm/transport/ws/support_test.go
+++ b/pkg/didcomm/transport/ws/support_test.go
@@ -21,6 +21,7 @@ import (
"github.com/stretchr/testify/require"
"nhooyr.io/websocket"
+ "github.com/hyperledger/aries-framework-go/pkg/common/model"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/service"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/decorator"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/transport"
@@ -66,13 +67,13 @@ func websocketClient(t *testing.T, port string) (*websocket.Conn, func()) {
func prepareDestination(endPoint string) *service.Destination {
return &service.Destination{
- ServiceEndpoint: endPoint,
+ ServiceEndpoint: model.Endpoint{URI: endPoint},
}
}
func prepareDestinationWithTransport(endPoint, returnRoute string, recipientKeys []string) *service.Destination {
return &service.Destination{
- ServiceEndpoint: endPoint,
+ ServiceEndpoint: model.Endpoint{URI: endPoint},
RecipientKeys: recipientKeys,
TransportReturnRoute: returnRoute,
}
diff --git a/pkg/doc/did/doc.go b/pkg/doc/did/doc.go
index 03bb2ee7c..5406db69b 100644
--- a/pkg/doc/did/doc.go
+++ b/pkg/doc/did/doc.go
@@ -21,6 +21,7 @@ import (
"github.com/multiformats/go-multibase"
"github.com/xeipuuv/gojsonschema"
+ "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"
"github.com/hyperledger/aries-framework-go/pkg/doc/signature/verifier"
@@ -364,9 +365,7 @@ type Service struct {
Type string `json:"type"`
Priority uint `json:"priority,omitempty"`
RecipientKeys []string `json:"recipientKeys,omitempty"`
- RoutingKeys []string `json:"routingKeys,omitempty"`
- ServiceEndpoint string `json:"serviceEndpoint"`
- Accept []string `json:"accept,omitempty"`
+ ServiceEndpoint model.Endpoint `json:"serviceEndpoint"`
Properties map[string]interface{} `json:"properties,omitempty"`
recipientKeysRelativeURL map[string]bool
routingKeysRelativeURL map[string]bool
@@ -634,6 +633,7 @@ func populateProofs(context, didID, baseURI string, rawProofs []interface{}) ([]
return proofs, nil
}
+//nolint:funlen
func populateServices(didID, baseURI string, rawServices []map[string]interface{}) []Service {
services := make([]Service, 0, len(rawServices))
@@ -661,10 +661,37 @@ func populateServices(didID, baseURI string, rawServices []map[string]interface{
routingKeys, routingKeysRelativeURL = populateKeys(routingKeys, didID, baseURI)
}
+ sp := model.Endpoint{
+ RoutingKeys: routingKeys,
+ }
+
+ //nolint:nestif
+ if epEntry, ok := rawService[jsonldServicePoint]; ok {
+ var (
+ uriStr string
+ accept []string
+ )
+
+ if uriStr, ok = epEntry.(string); ok {
+ sp.URI = uriStr
+ } else {
+ epMapEntry := mapEntry(epEntry)
+
+ if uriStr, ok = epMapEntry["uri"].(string); ok {
+ sp.URI = uriStr
+ }
+
+ if accept, ok = epMapEntry["accept"].([]string); ok {
+ sp.Accept = accept
+ }
+ }
+ }
+
service := Service{
ID: id, Type: stringEntry(rawService[jsonldType]), relativeURL: isRelative,
- ServiceEndpoint: stringEntry(rawService[jsonldServicePoint]), RecipientKeys: recipientKeys,
- RoutingKeys: routingKeys, Priority: uintEntry(rawService[jsonldPriority]),
+ ServiceEndpoint: sp,
+ RecipientKeys: recipientKeys,
+ Priority: uintEntry(rawService[jsonldPriority]),
recipientKeysRelativeURL: recipientKeysRelativeURL, routingKeysRelativeURL: routingKeysRelativeURL,
}
@@ -1269,7 +1296,7 @@ func populateRawServices(services []Service, didID, baseURI string) []map[string
routingKeys := make([]string, 0)
- for _, v := range services[i].RoutingKeys {
+ for _, v := range services[i].ServiceEndpoint.RoutingKeys {
if services[i].routingKeysRelativeURL[v] {
routingKeys = append(routingKeys, makeRelativeDIDURL(v, baseURI, didID))
continue
diff --git a/pkg/doc/did/doc_test.go b/pkg/doc/did/doc_test.go
index 71db2f52f..775cac4b6 100644
--- a/pkg/doc/did/doc_test.go
+++ b/pkg/doc/did/doc_test.go
@@ -23,6 +23,7 @@ import (
gojose "github.com/square/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"
@@ -143,17 +144,19 @@ func TestValidWithDocBase(t *testing.T) {
ID: "did:example:123456789abcdefghi#inbox",
Type: "SocialWebInboxService",
relativeURL: true,
- ServiceEndpoint: "https://social.example.com/83hfh37dj",
+ ServiceEndpoint: model.Endpoint{URI: "https://social.example.com/83hfh37dj"},
Properties: map[string]interface{}{"spamCost": map[string]interface{}{"amount": "0.50", "currency": "USD"}},
},
{
- ID: "did:example:123456789abcdefghi#did-communication",
- Type: "did-communication",
- Priority: 0,
- relativeURL: true,
- RecipientKeys: []string{"did:example:123456789abcdefghi#key2"},
- RoutingKeys: []string{"did:example:123456789abcdefghi#key2"},
- ServiceEndpoint: "https://agent.example.com/",
+ ID: "did:example:123456789abcdefghi#did-communication",
+ Type: "did-communication",
+ Priority: 0,
+ relativeURL: true,
+ RecipientKeys: []string{"did:example:123456789abcdefghi#key2"},
+ ServiceEndpoint: model.Endpoint{
+ URI: "https://agent.example.com/",
+ RoutingKeys: []string{"did:example:123456789abcdefghi#key2"},
+ },
Properties: map[string]interface{}{},
recipientKeysRelativeURL: map[string]bool{"did:example:123456789abcdefghi#key2": true},
routingKeysRelativeURL: map[string]bool{"did:example:123456789abcdefghi#key2": true},
@@ -250,16 +253,18 @@ func TestValid(t *testing.T) {
{
ID: "did:example:123456789abcdefghi#inbox",
Type: "SocialWebInboxService",
- ServiceEndpoint: "https://social.example.com/83hfh37dj",
+ ServiceEndpoint: model.Endpoint{URI: "https://social.example.com/83hfh37dj"},
Properties: map[string]interface{}{"spamCost": map[string]interface{}{"amount": "0.50", "currency": "USD"}},
},
{
- ID: "did:example:123456789abcdefghi#did-communication",
- Type: "did-communication",
- Priority: 0,
- RecipientKeys: []string{"did:example:123456789abcdefghi#key2"},
- RoutingKeys: []string{"did:example:123456789abcdefghi#key2"},
- ServiceEndpoint: "https://agent.example.com/",
+ ID: "did:example:123456789abcdefghi#did-communication",
+ Type: "did-communication",
+ Priority: 0,
+ RecipientKeys: []string{"did:example:123456789abcdefghi#key2"},
+ ServiceEndpoint: model.Endpoint{
+ URI: "https://agent.example.com/",
+ RoutingKeys: []string{"did:example:123456789abcdefghi#key2"},
+ },
Properties: map[string]interface{}{},
recipientKeysRelativeURL: map[string]bool{"did:example:123456789abcdefghi#key2": false},
routingKeysRelativeURL: map[string]bool{"did:example:123456789abcdefghi#key2": false},
diff --git a/pkg/doc/did/schema.go b/pkg/doc/did/schema.go
index 47f887100..7b9cf36a6 100644
--- a/pkg/doc/did/schema.go
+++ b/pkg/doc/did/schema.go
@@ -150,8 +150,30 @@ const (
"type": "string"
},
"serviceEndpoint": {
- "type": "string",
- "format": "uri"
+ "oneOf": [
+ {
+ "type": "object",
+ "minProperties": 1,
+ "properties": {
+ "uri": {
+ "type": "string",
+ "format": "uri"
+ },
+ "accept": {
+ "type": "array",
+ "items": [
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ },
+ {
+ "type": "string",
+ "format": "uri"
+ }
+ ]
}
}
}
@@ -299,8 +321,30 @@ const (
"type": "string"
},
"serviceEndpoint": {
- "type": "string",
- "format": "uri"
+ "oneOf": [
+ {
+ "type": "object",
+ "minProperties": 1,
+ "properties": {
+ "uri": {
+ "type": "string",
+ "format": "uri"
+ },
+ "accept": {
+ "type": "array",
+ "items": [
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ },
+ {
+ "type": "string",
+ "format": "uri"
+ }
+ ]
}
}
}
@@ -418,8 +462,30 @@ const (
"type": "string"
},
"serviceEndpoint": {
- "type": "string",
- "format": "uri"
+ "oneOf": [
+ {
+ "type": "object",
+ "minProperties": 1,
+ "properties": {
+ "uri": {
+ "type": "string",
+ "format": "uri"
+ },
+ "accept": {
+ "type": "array",
+ "items": [
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ },
+ {
+ "type": "string",
+ "format": "uri"
+ }
+ ]
}
}
}
diff --git a/pkg/doc/verifiable/credential_jwt_proof_test.go b/pkg/doc/verifiable/credential_jwt_proof_test.go
index 9af8ce513..59264b7fa 100644
--- a/pkg/doc/verifiable/credential_jwt_proof_test.go
+++ b/pkg/doc/verifiable/credential_jwt_proof_test.go
@@ -14,6 +14,7 @@ import (
"github.com/stretchr/testify/require"
+ "github.com/hyperledger/aries-framework-go/pkg/common/model"
"github.com/hyperledger/aries-framework-go/pkg/doc/did"
"github.com/hyperledger/aries-framework-go/pkg/doc/signature/verifier"
"github.com/hyperledger/aries-framework-go/pkg/kms"
@@ -239,7 +240,7 @@ func createDIDKeyFetcher(t *testing.T, pub ed25519.PublicKey, didID string) Publ
{
ID: fmt.Sprintf(didServiceID, id, 1),
Type: "did-communication",
- ServiceEndpoint: "http://localhost:47582",
+ ServiceEndpoint: model.Endpoint{URI: "http://localhost:47582"},
Priority: 0,
RecipientKeys: []string{pubKeyID},
},
diff --git a/pkg/framework/aries/framework_test.go b/pkg/framework/aries/framework_test.go
index 2e6d93586..f8699aa97 100644
--- a/pkg/framework/aries/framework_test.go
+++ b/pkg/framework/aries/framework_test.go
@@ -23,6 +23,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/hyperledger/aries-framework-go/component/storageutil/mem"
+ "github.com/hyperledger/aries-framework-go/pkg/common/model"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/service"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/dispatcher"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/packer"
@@ -125,7 +126,7 @@ func TestFramework(t *testing.T) {
e := ctx.OutboundDispatcher().Send(
[]byte("Hello World"),
mockdiddoc.MockDIDKey(t),
- &service.Destination{ServiceEndpoint: serverURL},
+ &service.Destination{ServiceEndpoint: model.Endpoint{URI: serverURL}},
)
require.NoError(t, e)
})
@@ -582,10 +583,12 @@ func TestFramework(t *testing.T) {
&didcomm.MockOutboundTransport{ExpectedResponse: "data1"}))
require.NoError(t, err)
require.Equal(t, 2, len(aries.outboundTransports))
- r, err := aries.outboundTransports[0].Send([]byte("data"), &service.Destination{ServiceEndpoint: "url"})
+ r, err := aries.outboundTransports[0].Send([]byte("data"),
+ &service.Destination{ServiceEndpoint: model.Endpoint{URI: "url"}})
require.NoError(t, err)
require.Equal(t, "data", r)
- r, err = aries.outboundTransports[1].Send([]byte("data1"), &service.Destination{ServiceEndpoint: "url"})
+ r, err = aries.outboundTransports[1].Send([]byte("data1"),
+ &service.Destination{ServiceEndpoint: model.Endpoint{URI: "url"}})
require.NoError(t, err)
require.Equal(t, "data1", r)
require.NoError(t, aries.Close())
diff --git a/pkg/framework/context/context_test.go b/pkg/framework/context/context_test.go
index 459d485b7..329de25f3 100644
--- a/pkg/framework/context/context_test.go
+++ b/pkg/framework/context/context_test.go
@@ -17,6 +17,7 @@ import (
"github.com/google/uuid"
"github.com/stretchr/testify/require"
+ "github.com/hyperledger/aries-framework-go/pkg/common/model"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/middleware"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/service"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/dispatcher/inbound"
@@ -768,10 +769,13 @@ func TestNewProvider(t *testing.T) {
&mockdidcomm.MockOutboundTransport{ExpectedResponse: "data1"}))
require.NoError(t, err)
require.Len(t, prov.OutboundTransports(), 2)
- r, err := prov.outboundTransports[0].Send([]byte("data"), &service.Destination{ServiceEndpoint: "url"})
+ r, err := prov.outboundTransports[0].Send([]byte("data"),
+ &service.Destination{ServiceEndpoint: model.Endpoint{URI: "url"}},
+ )
require.NoError(t, err)
require.Equal(t, "data", r)
- r, err = prov.outboundTransports[1].Send([]byte("data1"), &service.Destination{ServiceEndpoint: "url"})
+ r, err = prov.outboundTransports[1].Send([]byte("data1"),
+ &service.Destination{ServiceEndpoint: model.Endpoint{URI: "url"}})
require.NoError(t, err)
require.Equal(t, "data1", r)
})
diff --git a/pkg/mock/diddoc/mock_diddoc.go b/pkg/mock/diddoc/mock_diddoc.go
index ebe220352..7a2245015 100644
--- a/pkg/mock/diddoc/mock_diddoc.go
+++ b/pkg/mock/diddoc/mock_diddoc.go
@@ -13,6 +13,7 @@ import (
"github.com/btcsuite/btcutil/base58"
"github.com/stretchr/testify/require"
+ "github.com/hyperledger/aries-framework-go/pkg/common/model"
"github.com/hyperledger/aries-framework-go/pkg/doc/did"
"github.com/hyperledger/aries-framework-go/pkg/vdr/fingerprint"
)
@@ -26,11 +27,13 @@ func GetMockDIDDoc(t *testing.T) *did.Doc {
ID: "did:peer:123456789abcdefghi",
Service: []did.Service{
{
- ServiceEndpoint: "https://localhost:8090",
- Type: "did-communication",
- Priority: 0,
- RecipientKeys: []string{MockDIDKey(t)},
- RoutingKeys: []string{MockDIDKey(t)},
+ ServiceEndpoint: model.Endpoint{
+ URI: "https://localhost:8090",
+ RoutingKeys: []string{MockDIDKey(t)},
+ },
+ Type: "did-communication",
+ Priority: 0,
+ RecipientKeys: []string{MockDIDKey(t)},
},
},
VerificationMethod: []did.VerificationMethod{
@@ -69,16 +72,20 @@ func GetLegacyInteropMockDIDDoc(t *testing.T, id string, ed25519PubKey []byte) *
ID: peerDID,
Service: []did.Service{
{
- ServiceEndpoint: "https://localhost:8090",
- Type: "did-communication",
- Priority: 0,
- RecipientKeys: []string{pubKeyBase58},
+ ServiceEndpoint: model.Endpoint{
+ URI: "https://localhost:8090",
+ },
+ Type: "did-communication",
+ Priority: 0,
+ RecipientKeys: []string{pubKeyBase58},
},
{
- ServiceEndpoint: "https://localhost:8090",
- Type: "IndyAgent",
- Priority: 0,
- RecipientKeys: []string{pubKeyBase58},
+ ServiceEndpoint: model.Endpoint{
+ URI: "https://localhost:8090",
+ },
+ Type: "IndyAgent",
+ Priority: 0,
+ RecipientKeys: []string{pubKeyBase58},
},
},
VerificationMethod: []did.VerificationMethod{
@@ -129,11 +136,13 @@ func GetMockDIDDocWithDIDCommV2Bloc(t *testing.T, id string) *did.Doc {
ID: peerDID,
Service: []did.Service{
{
- ServiceEndpoint: "https://localhost:8090",
- Type: "DIDCommMessaging",
- Priority: 0,
- RecipientKeys: []string{MockDIDKey(t)},
- RoutingKeys: []string{MockDIDKey(t)},
+ ServiceEndpoint: model.Endpoint{
+ URI: "https://localhost:8090",
+ RoutingKeys: []string{MockDIDKey(t)},
+ },
+ Type: "DIDCommMessaging",
+ Priority: 0,
+ RecipientKeys: []string{MockDIDKey(t)},
},
},
VerificationMethod: []did.VerificationMethod{
@@ -188,11 +197,13 @@ func GetMockIndyDoc(t *testing.T) *did.Doc {
},
Service: []did.Service{
{
- ID: "did:sov:AyRHrP7u6rF1dKViGf5shA;indy",
- Type: "IndyAgent",
- Priority: 0,
- RecipientKeys: []string{"6SFxbqdqGKtVVmLvXDnq9JP4ziZCG2fJzETpMYHt1VNx"},
- ServiceEndpoint: "https://localhost:8090",
+ ID: "did:sov:AyRHrP7u6rF1dKViGf5shA;indy",
+ Type: "IndyAgent",
+ Priority: 0,
+ RecipientKeys: []string{"6SFxbqdqGKtVVmLvXDnq9JP4ziZCG2fJzETpMYHt1VNx"},
+ ServiceEndpoint: model.Endpoint{
+ URI: "https://localhost:8090",
+ },
},
},
Authentication: []did.Verification{
diff --git a/pkg/mock/vdr/mock_registry.go b/pkg/mock/vdr/mock_registry.go
index 1de37af30..7b00cbc52 100644
--- a/pkg/mock/vdr/mock_registry.go
+++ b/pkg/mock/vdr/mock_registry.go
@@ -11,6 +11,7 @@ import (
"crypto/rand"
"time"
+ "github.com/hyperledger/aries-framework-go/pkg/common/model"
"github.com/hyperledger/aries-framework-go/pkg/doc/did"
vdrapi "github.com/hyperledger/aries-framework-go/pkg/framework/aries/api/vdr"
)
@@ -101,11 +102,13 @@ func createDefaultDID() *did.Doc {
}
service := did.Service{
- ID: "did:example:123456789abcdefghi#did-communication",
- Type: "did-communication",
- ServiceEndpoint: "https://agent.example.com/",
- RecipientKeys: []string{creator},
- Priority: 0,
+ ID: "did:example:123456789abcdefghi#did-communication",
+ Type: "did-communication",
+ ServiceEndpoint: model.Endpoint{
+ URI: "https://agent.example.com/",
+ },
+ RecipientKeys: []string{creator},
+ Priority: 0,
}
signingKey := did.VerificationMethod{
diff --git a/pkg/store/connection/connection_lookup.go b/pkg/store/connection/connection_lookup.go
index 9c66c4c72..9496b502d 100644
--- a/pkg/store/connection/connection_lookup.go
+++ b/pkg/store/connection/connection_lookup.go
@@ -16,6 +16,7 @@ import (
"strings"
"github.com/hyperledger/aries-framework-go/pkg/common/log"
+ "github.com/hyperledger/aries-framework-go/pkg/common/model"
didcomm "github.com/hyperledger/aries-framework-go/pkg/didcomm/common/service"
"github.com/hyperledger/aries-framework-go/spi/storage"
)
@@ -61,14 +62,12 @@ type Record struct {
TheirLabel string
TheirDID string
MyDID string
- ServiceEndPoint string // ServiceEndPoint is 'their' DIDComm service endpoint.
- RecipientKeys []string // RecipientKeys holds 'their' DIDComm recipient keys.
- RoutingKeys []string // RoutingKeys holds 'their' DIDComm routing keys.
+ ServiceEndPoint model.Endpoint // ServiceEndPoint is 'their' DIDComm service endpoint.
+ RecipientKeys []string // RecipientKeys holds 'their' DIDComm recipient keys.
InvitationID string
InvitationDID string
Implicit bool
Namespace string
- MediaTypeProfiles []string
DIDCommVersion didcomm.Version
PeerDIDInitialState string
MyDIDRotation *DIDRotationRecord `json:"myDIDRotation,omitempty"`
diff --git a/pkg/store/did/store_test.go b/pkg/store/did/store_test.go
index 11e17df6f..a17f98fdb 100644
--- a/pkg/store/did/store_test.go
+++ b/pkg/store/did/store_test.go
@@ -17,6 +17,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/hyperledger/aries-framework-go/component/storageutil/mem"
+ "github.com/hyperledger/aries-framework-go/pkg/common/model"
"github.com/hyperledger/aries-framework-go/pkg/doc/did"
mockprovider "github.com/hyperledger/aries-framework-go/pkg/mock/provider"
mockstore "github.com/hyperledger/aries-framework-go/pkg/mock/storage"
@@ -257,7 +258,7 @@ func createDIDDocWithKey(pub string) *did.Doc {
{
ID: fmt.Sprintf(didServiceID, id, 1),
Type: "did-communication",
- ServiceEndpoint: "http://localhost:58416",
+ ServiceEndpoint: model.Endpoint{URI: "http://localhost:58416"},
Priority: 0,
RecipientKeys: []string{pubKeyID},
},
diff --git a/pkg/vdr/peer/creator.go b/pkg/vdr/peer/creator.go
index 29af7f088..037f331b0 100644
--- a/pkg/vdr/peer/creator.go
+++ b/pkg/vdr/peer/creator.go
@@ -89,13 +89,13 @@ func build(didDoc *did.Doc, docOpts *vdrapi.DIDMethodOpts) (*did.DocResolution,
didDoc.Service[i].Type = v
}
- if didDoc.Service[i].ServiceEndpoint == "" && docOpts.Values[DefaultServiceEndpoint] != nil {
+ if didDoc.Service[i].ServiceEndpoint.URI == "" && docOpts.Values[DefaultServiceEndpoint] != nil {
v, ok := docOpts.Values[DefaultServiceEndpoint].(string)
if !ok {
return nil, fmt.Errorf("defaultServiceEndpoint not string")
}
- didDoc.Service[i].ServiceEndpoint = v
+ didDoc.Service[i].ServiceEndpoint.URI = v
}
applyDIDCommKeys(i, didDoc)
diff --git a/pkg/vdr/peer/creator_test.go b/pkg/vdr/peer/creator_test.go
index f50165c71..e7bbc6edd 100644
--- a/pkg/vdr/peer/creator_test.go
+++ b/pkg/vdr/peer/creator_test.go
@@ -15,6 +15,7 @@ import (
"github.com/stretchr/testify/require"
+ "github.com/hyperledger/aries-framework-go/pkg/common/model"
"github.com/hyperledger/aries-framework-go/pkg/doc/did"
"github.com/hyperledger/aries-framework-go/pkg/doc/util/jwkkid"
"github.com/hyperledger/aries-framework-go/pkg/framework/aries/api/vdr"
@@ -74,9 +75,11 @@ func TestDIDCreator(t *testing.T) {
routingKeys := []string{"abc", "xyz"}
docResolution, err := c.Create(
&did.Doc{VerificationMethod: []did.VerificationMethod{getSigningKey()}, Service: []did.Service{{
- ServiceEndpoint: "request-endpoint",
- Type: "request-type",
- RoutingKeys: routingKeys,
+ ServiceEndpoint: model.Endpoint{
+ URI: "request-endpoint",
+ RoutingKeys: routingKeys,
+ },
+ Type: "request-type",
}}})
require.NoError(t, err)
@@ -85,8 +88,8 @@ func TestDIDCreator(t *testing.T) {
// verify service not empty, type and endpoint from request options
require.NotEmpty(t, docResolution.DIDDocument.Service)
require.Equal(t, "request-type", docResolution.DIDDocument.Service[0].Type)
- require.Equal(t, "request-endpoint", docResolution.DIDDocument.Service[0].ServiceEndpoint)
- require.Equal(t, routingKeys, docResolution.DIDDocument.Service[0].RoutingKeys)
+ require.Equal(t, "request-endpoint", docResolution.DIDDocument.Service[0].ServiceEndpoint.URI)
+ require.Equal(t, routingKeys, docResolution.DIDDocument.Service[0].ServiceEndpoint.RoutingKeys)
})
t.Run("test request overrides with keyAgreement", func(t *testing.T) {
@@ -100,9 +103,11 @@ func TestDIDCreator(t *testing.T) {
docResolution, err := c.Create(
&did.Doc{
VerificationMethod: []did.VerificationMethod{sVM}, Service: []did.Service{{
- ServiceEndpoint: "request-endpoint",
- Type: "request-type",
- RoutingKeys: routingKeys,
+ ServiceEndpoint: model.Endpoint{
+ URI: "request-endpoint",
+ RoutingKeys: routingKeys,
+ },
+ Type: "request-type",
}},
KeyAgreement: []did.Verification{eVM},
})
@@ -113,8 +118,8 @@ func TestDIDCreator(t *testing.T) {
// verify service not empty, type and endpoint from request options
require.NotEmpty(t, docResolution.DIDDocument.Service)
require.Equal(t, "request-type", docResolution.DIDDocument.Service[0].Type)
- require.Equal(t, "request-endpoint", docResolution.DIDDocument.Service[0].ServiceEndpoint)
- require.Equal(t, routingKeys, docResolution.DIDDocument.Service[0].RoutingKeys)
+ require.Equal(t, "request-endpoint", docResolution.DIDDocument.Service[0].ServiceEndpoint.URI)
+ require.Equal(t, routingKeys, docResolution.DIDDocument.Service[0].ServiceEndpoint.RoutingKeys)
// verify KeyAgreement
require.Len(t, docResolution.DIDDocument.KeyAgreement, 1)
diff --git a/pkg/vdr/verifiable_compat_test.go b/pkg/vdr/verifiable_compat_test.go
index 8b2087649..32a1f6a90 100644
--- a/pkg/vdr/verifiable_compat_test.go
+++ b/pkg/vdr/verifiable_compat_test.go
@@ -17,6 +17,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/hyperledger/aries-framework-go/component/storageutil/mem"
+ "github.com/hyperledger/aries-framework-go/pkg/common/model"
"github.com/hyperledger/aries-framework-go/pkg/crypto"
"github.com/hyperledger/aries-framework-go/pkg/doc/did"
"github.com/hyperledger/aries-framework-go/pkg/doc/signature/suite"
@@ -152,7 +153,7 @@ func createPeerDIDLikeDIDExchangeService(t *testing.T, a *context.Provider) *did
docResolution, err := a.VDRegistry().Create(
peer.DIDMethod, &did.Doc{
Service: []did.Service{
- {ServiceEndpoint: "http://example.com/didcomm"},
+ {ServiceEndpoint: model.Endpoint{URI: "http://example.com/didcomm"}},
},
VerificationMethod: []did.VerificationMethod{
authVM,
diff --git a/pkg/wallet/invitation.go b/pkg/wallet/invitation.go
index c962682b2..4944acb22 100644
--- a/pkg/wallet/invitation.go
+++ b/pkg/wallet/invitation.go
@@ -40,7 +40,7 @@ type GenericInvitation struct {
From string `json:"from,omitempty"`
Label string `json:"label,omitempty"`
Goal string `json:"goal,omitempty"`
- GoalCode string `json:"goal-code,omitempty"`
+ GoalCode string `json:"goal_code,omitempty"`
Services []interface{} `json:"services"`
Accept []string `json:"accept,omitempty"`
Protocols []string `json:"handshake_protocols,omitempty"`
diff --git a/test/bdd/features/waci_issuance_didcomm_v1.feature b/test/bdd/features/waci_issuance_didcomm_v1.feature
index b36e11282..f8910a28c 100644
--- a/test/bdd/features/waci_issuance_didcomm_v1.feature
+++ b/test/bdd/features/waci_issuance_didcomm_v1.feature
@@ -19,7 +19,7 @@ Feature: WACI Issuance (Go API, DIDComm V1 + Issue Credential V2)
And "Holder" creates public DID for did method "sidetree"
Then "Issuer" waits for public did to become available in sidetree for up to 10 seconds
And "Holder" waits for public did to become available in sidetree for up to 10 seconds
- Then "Issuer" creates an out-of-band-v1 invitation with streamlined-vc goal-code
+ Then "Issuer" creates an out-of-band-v1 invitation with streamlined-vc goal_code
And "Issuer" sends the out-of-band-v1 invitation to "Holder" and they accept it
Then "Holder" sends proposal credential V2 to the "Issuer" (WACI, DIDComm V1)
And "Issuer" accepts a proposal V2 and sends an offer to the Holder (WACI, DIDComm V1)
diff --git a/test/bdd/features/waci_issuance_didcomm_v2.feature b/test/bdd/features/waci_issuance_didcomm_v2.feature
index d073ce05e..0dd106cea 100644
--- a/test/bdd/features/waci_issuance_didcomm_v2.feature
+++ b/test/bdd/features/waci_issuance_didcomm_v2.feature
@@ -19,7 +19,7 @@ Feature: WACI Issuance (Go API, DIDComm V2 + Issue Credential V3)
And "Holder" creates public DID for did method "sidetree"
Then "Issuer" waits for public did to become available in sidetree for up to 10 seconds
And "Holder" waits for public did to become available in sidetree for up to 10 seconds
- Then "Issuer" creates an out-of-band-v2 invitation with streamlined-vc goal-code
+ Then "Issuer" creates an out-of-band-v2 invitation with streamlined-vc goal_code
And "Issuer" sends the request to "Holder" and they accept it
Then "Holder" sends proposal credential V3 to the "Issuer" (WACI)
And "Issuer" accepts a proposal V3 and sends an offer to the Holder (WACI)
diff --git a/test/bdd/pkg/connection/connection_sdk_steps.go b/test/bdd/pkg/connection/connection_sdk_steps.go
index 3021cb488..b776a2db9 100644
--- a/test/bdd/pkg/connection/connection_sdk_steps.go
+++ b/test/bdd/pkg/connection/connection_sdk_steps.go
@@ -179,7 +179,6 @@ func (s *SDKSteps) createConnection(agentCtx *context.Provider, myDID string, ta
conn.ServiceEndPoint = destination.ServiceEndpoint
conn.RecipientKeys = destination.RecipientKeys
- conn.RoutingKeys = destination.RoutingKeys
didConnStore := agentCtx.DIDConnectionStore()
diff --git a/test/bdd/pkg/waci/waci_issuance_didcomm_v1_sdk_steps.go b/test/bdd/pkg/waci/waci_issuance_didcomm_v1_sdk_steps.go
index 54bbe6cf3..9a13682ee 100644
--- a/test/bdd/pkg/waci/waci_issuance_didcomm_v1_sdk_steps.go
+++ b/test/bdd/pkg/waci/waci_issuance_didcomm_v1_sdk_steps.go
@@ -76,7 +76,7 @@ func (i *IssuanceSDKDIDCommV1Steps) SetContext(ctx *context.BDDContext) {
// RegisterSteps registers the BDD test steps on the suite.
// Note that VC proofs are not checked in this test suite.
func (i *IssuanceSDKDIDCommV1Steps) RegisterSteps(suite *godog.Suite) {
- suite.Step(`^"([^"]*)" creates an out-of-band-v1 invitation with streamlined-vc goal-code$`,
+ suite.Step(`^"([^"]*)" creates an out-of-band-v1 invitation with streamlined-vc goal_code$`,
i.createOOBV1WithStreamlinedVCGoalCode)
suite.Step(`^"([^"]*)" sends the out-of-band-v1 invitation to "([^"]*)" and they accept it$`,
i.acceptOOBV1Invitation)
diff --git a/test/bdd/pkg/waci/waci_issuance_didcomm_v2_sdk_steps.go b/test/bdd/pkg/waci/waci_issuance_didcomm_v2_sdk_steps.go
index 513af5462..e5adadce6 100644
--- a/test/bdd/pkg/waci/waci_issuance_didcomm_v2_sdk_steps.go
+++ b/test/bdd/pkg/waci/waci_issuance_didcomm_v2_sdk_steps.go
@@ -79,7 +79,7 @@ func (i *IssuanceSDKDIDCommV2Steps) SetContext(ctx *context.BDDContext) {
// RegisterSteps registers the BDD test steps on the suite.
// Note that VC proofs are not checked in this test suite.
func (i *IssuanceSDKDIDCommV2Steps) RegisterSteps(suite *godog.Suite) {
- suite.Step(`^"([^"]*)" creates an out-of-band-v2 invitation with streamlined-vc goal-code$`,
+ suite.Step(`^"([^"]*)" creates an out-of-band-v2 invitation with streamlined-vc goal_code$`,
i.createOOBV2WithStreamlinedVCGoalCode)
suite.Step(`^"([^"]*)" sends the request to "([^"]*)" and they accept it$`, i.acceptOOBV2Invitation)
suite.Step(`^"([^"]*)" sends proposal credential V3 to the "([^"]*)" \(WACI\)$`, i.sendsProposalV3)
From 85a735d803f23153e7e5931db4c8f64451936250 Mon Sep 17 00:00:00 2001
From: Firas Qutishat
Date: Wed, 27 Apr 2022 09:42:08 -0400
Subject: [PATCH 27/54] feat: add HealthCheck for remote kms
Signed-off-by: Firas Qutishat
---
pkg/kms/webkms/remotekms.go | 23 +++++++++++++++++++++++
pkg/kms/webkms/remotekms_test.go | 21 +++++++++++++++++++++
2 files changed, 44 insertions(+)
diff --git a/pkg/kms/webkms/remotekms.go b/pkg/kms/webkms/remotekms.go
index b93fa8f64..552c494b2 100644
--- a/pkg/kms/webkms/remotekms.go
+++ b/pkg/kms/webkms/remotekms.go
@@ -15,6 +15,7 @@ import (
"io"
"io/ioutil"
"net/http"
+ "net/url"
"strings"
"time"
@@ -305,6 +306,28 @@ func (r *RemoteKMS) createKey(kt kms.KeyType) (string, []byte, error) {
return httpResp.KeyURL, httpResp.PublicKey, nil
}
+// HealthCheck check kms.
+func (r *RemoteKMS) HealthCheck() error {
+ parseURL, err := url.Parse(r.keystoreURL)
+ if err != nil {
+ return err
+ }
+
+ resp, err := r.getHTTPRequest(parseURL.Scheme + "://" + parseURL.Host + "/healthcheck")
+ if err != nil {
+ return err
+ }
+
+ // handle response
+ defer closeResponseBody(resp.Body, logger, "HealthCheck")
+
+ if resp.StatusCode != http.StatusOK {
+ return fmt.Errorf("kms health check return %d status code", resp.StatusCode)
+ }
+
+ return nil
+}
+
// Get key handle for the given KeyID remotely
// Returns:
// - handle instance representing a remote keystore URL including KeyID
diff --git a/pkg/kms/webkms/remotekms_test.go b/pkg/kms/webkms/remotekms_test.go
index 816475442..2a56298be 100644
--- a/pkg/kms/webkms/remotekms_test.go
+++ b/pkg/kms/webkms/remotekms_test.go
@@ -272,6 +272,27 @@ func TestCreateKeyWithLocationInResponseBody(t *testing.T) {
require.Contains(t, err.Error(), "failingUnmarshal always fails")
}
+func TestHealthCheck(t *testing.T) {
+ hf := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ w.WriteHeader(http.StatusServiceUnavailable)
+ })
+
+ server, url, client := CreateMockHTTPServerAndClient(t, hf)
+ defaultKeystoreURL := fmt.Sprintf("%s/%s", strings.ReplaceAll(KeystoreEndpoint,
+ "{serverEndpoint}", url), defaultKeyStoreID)
+
+ defer func() {
+ e := server.Close()
+ require.NoError(t, e)
+ }()
+
+ remoteKMS := New(defaultKeystoreURL, client)
+
+ err := remoteKMS.HealthCheck()
+ require.Error(t, err)
+ require.Contains(t, err.Error(), "kms health check return 503 status code")
+}
+
func TestRemoteKeyStoreWithHeadersFunc(t *testing.T) {
xRootCapabilityHeaderValue := []byte("DUMMY")
From ae41d52af25a5c640d1bf8cc24c2d2ea024287f3 Mon Sep 17 00:00:00 2001
From: Christian Nuss
Date: Wed, 27 Apr 2022 11:09:25 -0700
Subject: [PATCH 28/54] externalize agent parameters + router (#3229)
fix: vc-revocation-list-2021 context
Signed-off-by: Firas Qutishat
Signed-off-by: Christian Nuss
* externalize agent parameters + router
Signed-off-by: Christian Nuss
* fix linting issues
Signed-off-by: Christian Nuss
* feat: In-memory store "ping" method
The method always returns nil. It's there just to allow it to implement a "Pinger" sort of interface which may be defined somewhere.
Signed-off-by: Derek Trider
Signed-off-by: Christian Nuss
* remove unused nolint
Signed-off-by: Christian Nuss
* fix linting issues
Signed-off-by: Christian Nuss
* signoff
Signed-off-by: Christian Nuss
* add NewAgentParameters test
Signed-off-by: Christian Nuss
* use t.Setenv
Signed-off-by: Christian Nuss
* linting
Signed-off-by: Christian Nuss
Co-authored-by: Firas Qutishat
Co-authored-by: Derek Trider
---
cmd/aries-agent-rest/startcmd/start.go | 269 +++++++++++---------
cmd/aries-agent-rest/startcmd/start_test.go | 128 ++++++++--
2 files changed, 256 insertions(+), 141 deletions(-)
diff --git a/cmd/aries-agent-rest/startcmd/start.go b/cmd/aries-agent-rest/startcmd/start.go
index 6775c034c..3c5f39e9f 100644
--- a/cmd/aries-agent-rest/startcmd/start.go
+++ b/cmd/aries-agent-rest/startcmd/start.go
@@ -233,7 +233,8 @@ var (
}
)
-type agentParameters struct {
+// AgentParameters represents the various options to run an Aries Agent.
+type AgentParameters struct {
server server
host, defaultLabel, transportReturnRoute string
tlsCertFile, tlsKeyFile string
@@ -289,144 +290,153 @@ func Cmd(server server) (*cobra.Command, error) {
return startCmd, nil
}
-func createStartCMD(server server) *cobra.Command { //nolint: funlen,gocyclo,gocognit
- return &cobra.Command{
- Use: "start",
- Short: "Start an agent",
- Long: `Start an Aries agent controller`,
- RunE: func(cmd *cobra.Command, args []string) error {
- // log level
- logLevel, err := getUserSetVar(cmd, agentLogLevelFlagName, agentLogLevelEnvKey, true)
- if err != nil {
- return err
- }
+// NewAgentParameters constructs AgentParameters with the given cobra command.
+func NewAgentParameters(server server, cmd *cobra.Command) (*AgentParameters, error) { //nolint: funlen,gocyclo
+ // log level
+ logLevel, err := getUserSetVar(cmd, agentLogLevelFlagName, agentLogLevelEnvKey, true)
+ if err != nil {
+ return nil, err
+ }
- err = setLogLevel(logLevel)
- if err != nil {
- return err
- }
+ err = setLogLevel(logLevel)
+ if err != nil {
+ return nil, err
+ }
- host, err := getUserSetVar(cmd, agentHostFlagName, agentHostEnvKey, false)
- if err != nil {
- return err
- }
+ host, err := getUserSetVar(cmd, agentHostFlagName, agentHostEnvKey, false)
+ if err != nil {
+ return nil, err
+ }
- token, err := getUserSetVar(cmd, agentTokenFlagName, agentTokenEnvKey, true)
- if err != nil {
- return err
- }
+ token, err := getUserSetVar(cmd, agentTokenFlagName, agentTokenEnvKey, true)
+ if err != nil {
+ return nil, err
+ }
- inboundHosts, err := getUserSetVars(cmd, agentInboundHostFlagName, agentInboundHostEnvKey, true)
- if err != nil {
- return err
- }
+ inboundHosts, err := getUserSetVars(cmd, agentInboundHostFlagName, agentInboundHostEnvKey, true)
+ if err != nil {
+ return nil, err
+ }
- inboundHostExternals, err := getUserSetVars(cmd, agentInboundHostExternalFlagName,
- agentInboundHostExternalEnvKey, true)
- if err != nil {
- return err
- }
+ inboundHostExternals, err := getUserSetVars(cmd, agentInboundHostExternalFlagName,
+ agentInboundHostExternalEnvKey, true)
+ if err != nil {
+ return nil, err
+ }
- websocketReadLimit, err := getWebSocketReadLimit(cmd)
- if err != nil {
- return err
- }
+ websocketReadLimit, err := getWebSocketReadLimit(cmd)
+ if err != nil {
+ return nil, err
+ }
- dbParam, err := getDBParam(cmd)
- if err != nil {
- return err
- }
+ dbParam, err := getDBParam(cmd)
+ if err != nil {
+ return nil, err
+ }
- defaultLabel, err := getUserSetVar(cmd, agentDefaultLabelFlagName, agentDefaultLabelEnvKey, true)
- if err != nil {
- return err
- }
+ defaultLabel, err := getUserSetVar(cmd, agentDefaultLabelFlagName, agentDefaultLabelEnvKey, true)
+ if err != nil {
+ return nil, err
+ }
- autoAccept, err := getAutoAcceptValue(cmd)
- if err != nil {
- return err
- }
+ autoAccept, err := getAutoAcceptValue(cmd)
+ if err != nil {
+ return nil, err
+ }
- webhookURLs, err := getUserSetVars(cmd, agentWebhookFlagName, agentWebhookEnvKey, autoAccept)
- if err != nil {
- return err
- }
+ webhookURLs, err := getUserSetVars(cmd, agentWebhookFlagName, agentWebhookEnvKey, autoAccept)
+ if err != nil {
+ return nil, err
+ }
- httpResolvers, err := getUserSetVars(cmd, agentHTTPResolverFlagName, agentHTTPResolverEnvKey, true)
- if err != nil {
- return err
- }
+ httpResolvers, err := getUserSetVars(cmd, agentHTTPResolverFlagName, agentHTTPResolverEnvKey, true)
+ if err != nil {
+ return nil, err
+ }
- outboundTransports, err := getUserSetVars(cmd, agentOutboundTransportFlagName,
- agentOutboundTransportEnvKey, true)
- if err != nil {
- return err
- }
+ outboundTransports, err := getUserSetVars(cmd, agentOutboundTransportFlagName,
+ agentOutboundTransportEnvKey, true)
+ if err != nil {
+ return nil, err
+ }
- transportReturnRoute, err := getUserSetVar(cmd, agentTransportReturnRouteFlagName,
- agentTransportReturnRouteEnvKey, true)
- if err != nil {
- return err
- }
+ transportReturnRoute, err := getUserSetVar(cmd, agentTransportReturnRouteFlagName,
+ agentTransportReturnRouteEnvKey, true)
+ if err != nil {
+ return nil, err
+ }
- contextProviderURLs, err := getUserSetVars(cmd, agentContextProviderFlagName, agentContextProviderEnvKey, true)
- if err != nil {
- return err
- }
+ contextProviderURLs, err := getUserSetVars(cmd, agentContextProviderFlagName, agentContextProviderEnvKey, true)
+ if err != nil {
+ return nil, err
+ }
- autoExecuteRFC0593, err := getAutoExecuteRFC0593(cmd)
- if err != nil {
- return err
- }
+ autoExecuteRFC0593, err := getAutoExecuteRFC0593(cmd)
+ if err != nil {
+ return nil, err
+ }
- tlsCertFile, err := getUserSetVar(cmd, agentTLSCertFileFlagName, agentTLSCertFileEnvKey, true)
- if err != nil {
- return err
- }
+ tlsCertFile, err := getUserSetVar(cmd, agentTLSCertFileFlagName, agentTLSCertFileEnvKey, true)
+ if err != nil {
+ return nil, err
+ }
- tlsKeyFile, err := getUserSetVar(cmd, agentTLSKeyFileFlagName, agentTLSKeyFileEnvKey, true)
- if err != nil {
- return err
- }
+ tlsKeyFile, err := getUserSetVar(cmd, agentTLSKeyFileFlagName, agentTLSKeyFileEnvKey, true)
+ if err != nil {
+ return nil, err
+ }
- keyType, err := getUserSetVar(cmd, agentKeyTypeFlagName, agentKeyTypeEnvKey, true)
- if err != nil {
- return err
- }
+ keyType, err := getUserSetVar(cmd, agentKeyTypeFlagName, agentKeyTypeEnvKey, true)
+ if err != nil {
+ return nil, err
+ }
- keyAgreementType, err := getUserSetVar(cmd, agentKeyAgreementTypeFlagName, agentKeyAgreementTypeEnvKey, true)
- if err != nil {
- return err
- }
+ keyAgreementType, err := getUserSetVar(cmd, agentKeyAgreementTypeFlagName, agentKeyAgreementTypeEnvKey, true)
+ if err != nil {
+ return nil, err
+ }
- mediaTypeProfiles, err := getUserSetVars(cmd, agentMediaTypeProfilesFlagName, agentMediaTypeProfilesEnvKey, true)
+ mediaTypeProfiles, err := getUserSetVars(cmd, agentMediaTypeProfilesFlagName, agentMediaTypeProfilesEnvKey, true)
+ if err != nil {
+ return nil, err
+ }
+
+ parameters := &AgentParameters{
+ server: server,
+ host: host,
+ token: token,
+ inboundHostInternals: inboundHosts,
+ inboundHostExternals: inboundHostExternals,
+ websocketReadLimit: websocketReadLimit,
+ dbParam: dbParam,
+ defaultLabel: defaultLabel,
+ webhookURLs: webhookURLs,
+ httpResolvers: httpResolvers,
+ outboundTransports: outboundTransports,
+ autoAccept: autoAccept,
+ transportReturnRoute: transportReturnRoute,
+ contextProviderURLs: contextProviderURLs,
+ tlsCertFile: tlsCertFile,
+ tlsKeyFile: tlsKeyFile,
+ autoExecuteRFC0593: autoExecuteRFC0593,
+ keyType: keyType,
+ keyAgreementType: keyAgreementType,
+ mediaTypeProfiles: mediaTypeProfiles,
+ }
+
+ return parameters, nil
+}
+
+func createStartCMD(server server) *cobra.Command {
+ return &cobra.Command{
+ Use: "start",
+ Short: "Start an agent",
+ Long: `Start an Aries agent controller`,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ parameters, err := NewAgentParameters(server, cmd)
if err != nil {
return err
}
-
- parameters := &agentParameters{
- server: server,
- host: host,
- token: token,
- inboundHostInternals: inboundHosts,
- inboundHostExternals: inboundHostExternals,
- websocketReadLimit: websocketReadLimit,
- dbParam: dbParam,
- defaultLabel: defaultLabel,
- webhookURLs: webhookURLs,
- httpResolvers: httpResolvers,
- outboundTransports: outboundTransports,
- autoAccept: autoAccept,
- transportReturnRoute: transportReturnRoute,
- contextProviderURLs: contextProviderURLs,
- tlsCertFile: tlsCertFile,
- tlsKeyFile: tlsKeyFile,
- autoExecuteRFC0593: autoExecuteRFC0593,
- keyType: keyType,
- keyAgreementType: keyAgreementType,
- mediaTypeProfiles: mediaTypeProfiles,
- }
-
return startAgent(parameters)
},
}
@@ -585,7 +595,7 @@ func createFlags(startCmd *cobra.Command) {
}
func getUserSetVar(cmd *cobra.Command, flagName, envKey string, isOptional bool) (string, error) {
- if cmd.Flags().Changed(flagName) {
+ if cmd != nil && cmd.Flags().Changed(flagName) {
value, err := cmd.Flags().GetString(flagName)
if err != nil {
return "", fmt.Errorf(flagName+" flag not found: %s", err)
@@ -605,7 +615,7 @@ func getUserSetVar(cmd *cobra.Command, flagName, envKey string, isOptional bool)
}
func getUserSetVars(cmd *cobra.Command, flagName, envKey string, isOptional bool) ([]string, error) {
- if cmd.Flags().Changed(flagName) {
+ if cmd != nil && cmd.Flags().Changed(flagName) {
value, err := cmd.Flags().GetStringSlice(flagName)
if err != nil {
return nil, fmt.Errorf(flagName+" flag not found: %s", err)
@@ -775,9 +785,10 @@ func authorizationMiddleware(token string) mux.MiddlewareFunc {
return middleware
}
-func startAgent(parameters *agentParameters) error {
+// NewRouter returns a Router for the Aries Agent.
+func (parameters *AgentParameters) NewRouter() (*mux.Router, error) {
if parameters.host == "" {
- return errMissingHost
+ return nil, errMissingHost
}
// set message handler
@@ -785,7 +796,7 @@ func startAgent(parameters *agentParameters) error {
ctx, err := createAriesAgent(parameters)
if err != nil {
- return err
+ return nil, err
}
// get all HTTP REST API handlers available for controller API
@@ -794,7 +805,7 @@ func startAgent(parameters *agentParameters) error {
controller.WithMessageHandler(parameters.msgHandler),
controller.WithAutoExecuteRFC0593(parameters.autoExecuteRFC0593))
if err != nil {
- return fmt.Errorf("failed to start aries agent rest on port [%s], failed to get rest service api : %w",
+ return nil, fmt.Errorf("failed to start aries agent rest on port [%s], failed to get rest service api : %w",
parameters.host, err)
}
@@ -808,7 +819,17 @@ func startAgent(parameters *agentParameters) error {
router.HandleFunc(handler.Path(), handler.Handle()).Methods(handler.Method())
}
+ return router, nil
+}
+
+func startAgent(parameters *AgentParameters) error {
logger.Infof("Starting aries agent rest on host [%s]", parameters.host)
+
+ router, err := parameters.NewRouter()
+ if err != nil {
+ return err
+ }
+
// start server on given port and serve using given handlers
handler := cors.New(
cors.Options{
@@ -826,7 +847,7 @@ func startAgent(parameters *agentParameters) error {
}
//nolint:funlen,gocyclo
-func createAriesAgent(parameters *agentParameters) (*context.Provider, error) {
+func createAriesAgent(parameters *AgentParameters) (*context.Provider, error) {
var opts []aries.Option
storePro, err := createStoreProviders(parameters)
@@ -898,7 +919,7 @@ func createAriesAgent(parameters *agentParameters) (*context.Provider, error) {
return ctx, nil
}
-func createStoreProviders(parameters *agentParameters) (storage.Provider, error) {
+func createStoreProviders(parameters *AgentParameters) (storage.Provider, error) {
provider, supported := supportedStorageProviders[parameters.dbParam.dbType]
if !supported {
return nil, fmt.Errorf("key database type not set to a valid type." +
diff --git a/cmd/aries-agent-rest/startcmd/start_test.go b/cmd/aries-agent-rest/startcmd/start_test.go
index b742076e6..61a382ad5 100644
--- a/cmd/aries-agent-rest/startcmd/start_test.go
+++ b/cmd/aries-agent-rest/startcmd/start_test.go
@@ -104,7 +104,7 @@ func TestStartAriesDRequests(t *testing.T) {
testInboundHostURL := randomURL()
go func() {
- parameters := &agentParameters{
+ parameters := &AgentParameters{
server: &HTTPServer{},
host: testHostURL,
inboundHostInternals: []string{httpProtocol + "@" + testInboundHostURL},
@@ -295,7 +295,7 @@ func TestStartCmdWithMissingHostArg(t *testing.T) {
}
func TestStartAgentWithBlankHost(t *testing.T) {
- parameters := &agentParameters{
+ parameters := &AgentParameters{
server: &mockServer{},
inboundHostInternals: []string{randomURL()},
}
@@ -535,7 +535,7 @@ func TestStartMultipleAgentsWithSameHost(t *testing.T) {
inboundHost2 := "localhost:8097"
go func() {
- parameters := &agentParameters{
+ parameters := &AgentParameters{
server: &HTTPServer{},
host: host,
inboundHostInternals: []string{httpProtocol + "@" + inboundHost},
@@ -548,7 +548,7 @@ func TestStartMultipleAgentsWithSameHost(t *testing.T) {
waitForServerToStart(t, host, inboundHost)
- parameters := &agentParameters{
+ parameters := &AgentParameters{
server: &HTTPServer{},
host: host,
inboundHostInternals: []string{httpProtocol + "@" + inboundHost2},
@@ -568,7 +568,7 @@ func TestStartAriesErrorWithResolvers(t *testing.T) {
testHostURL := randomURL()
testInboundHostURL := randomURL()
- parameters := &agentParameters{
+ parameters := &AgentParameters{
server: &HTTPServer{},
host: testHostURL,
inboundHostInternals: []string{httpProtocol + "@" + testInboundHostURL},
@@ -586,7 +586,7 @@ func TestStartAriesErrorWithResolvers(t *testing.T) {
testHostURL := randomURL()
testInboundHostURL := randomURL()
- parameters := &agentParameters{
+ parameters := &AgentParameters{
server: &HTTPServer{},
host: testHostURL,
inboundHostInternals: []string{httpProtocol + "@" + testInboundHostURL},
@@ -606,7 +606,7 @@ func TestStartAriesWithOutboundTransports(t *testing.T) {
testInboundHostURL := randomURL()
go func() {
- parameters := &agentParameters{
+ parameters := &AgentParameters{
server: &HTTPServer{},
host: testHostURL,
inboundHostInternals: []string{httpProtocol + "@" + testInboundHostURL},
@@ -627,7 +627,7 @@ func TestStartAriesWithOutboundTransports(t *testing.T) {
testHostURL := randomURL()
testInboundHostURL := randomURL()
- parameters := &agentParameters{
+ parameters := &AgentParameters{
server: &HTTPServer{},
host: testHostURL,
inboundHostInternals: []string{httpProtocol + "@" + testInboundHostURL},
@@ -647,7 +647,7 @@ func TestStartAriesWithInboundTransport(t *testing.T) {
testInboundHostURL := randomURL()
go func() {
- parameters := &agentParameters{
+ parameters := &AgentParameters{
server: &HTTPServer{},
host: testHostURL,
inboundHostInternals: []string{websocketProtocol + "@" + testInboundHostURL},
@@ -668,7 +668,7 @@ func TestStartAriesWithInboundTransport(t *testing.T) {
testHostURL := randomURL()
testInboundHostURL := randomURL()
- parameters := &agentParameters{
+ parameters := &AgentParameters{
server: &HTTPServer{},
host: testHostURL,
inboundHostInternals: []string{"wss" + "@" + testInboundHostURL},
@@ -687,7 +687,7 @@ func TestStartAriesWithAutoAccept(t *testing.T) {
testInboundHostURL := randomURL()
go func() {
- parameters := &agentParameters{
+ parameters := &AgentParameters{
server: &HTTPServer{},
host: testHostURL,
inboundHostInternals: []string{httpProtocol + "@" + testInboundHostURL},
@@ -706,7 +706,7 @@ func TestStartAriesWithAutoAccept(t *testing.T) {
}
func TestStartAriesTLS(t *testing.T) {
- parameters := &agentParameters{
+ parameters := &AgentParameters{
server: &HTTPServer{},
host: ":0",
dbParam: &dbParam{dbType: databaseTypeMemOption},
@@ -756,7 +756,7 @@ func TestCreateAriesWithKeyType(t *testing.T) {
for _, tt := range tests {
tc := tt
t.Run(tc.name, func(t *testing.T) {
- parameters := &agentParameters{
+ parameters := &AgentParameters{
dbParam: &dbParam{dbType: databaseTypeMemOption},
keyType: tc.kt,
}
@@ -794,7 +794,7 @@ func TestCreateAriesWithKeyAgreementType(t *testing.T) {
for _, tt := range tests {
tc := tt
t.Run(tc.name, func(t *testing.T) {
- parameters := &agentParameters{
+ parameters := &AgentParameters{
dbParam: &dbParam{dbType: databaseTypeMemOption},
keyAgreementType: tc.kt,
}
@@ -832,7 +832,7 @@ func TestCreateAriesWithMediaTypeProfiles(t *testing.T) {
for _, tt := range tests {
tc := tt
t.Run(tc.name, func(t *testing.T) {
- parameters := &agentParameters{
+ parameters := &AgentParameters{
dbParam: &dbParam{dbType: databaseTypeMemOption},
mediaTypeProfiles: tc.mtp,
}
@@ -854,7 +854,7 @@ func TestStartAriesWithAuthorization(t *testing.T) {
testInboundHostURL := randomURL()
go func() {
- parameters := &agentParameters{
+ parameters := &AgentParameters{
server: &HTTPServer{},
host: testHostURL,
token: goodToken,
@@ -893,7 +893,7 @@ func TestStartAriesWithAuthorization(t *testing.T) {
func TestStoreProvider(t *testing.T) {
t.Run("test invalid database type", func(t *testing.T) {
- _, err := createAriesAgent(&agentParameters{dbParam: &dbParam{dbType: "data1"}})
+ _, err := createAriesAgent(&AgentParameters{dbParam: &dbParam{dbType: "data1"}})
require.Error(t, err)
require.Contains(t, err.Error(), "database type not set to a valid type")
})
@@ -926,6 +926,100 @@ func TestStartCmdInvalidAutoExecuteRFC0593Value(t *testing.T) {
require.Contains(t, err.Error(), "invalid syntax")
}
+// nolint: errcheck,gosec
+func TestNewAgentParametersUsingEnv(t *testing.T) {
+ os.Setenv(agentHostEnvKey, "agentHost")
+ defer os.Unsetenv(agentHostEnvKey)
+
+ os.Setenv(agentTokenEnvKey, "agentToken")
+ defer os.Unsetenv(agentTokenEnvKey)
+
+ os.Setenv(databaseTypeEnvKey, "databaseType")
+ defer os.Unsetenv(databaseTypeEnvKey)
+
+ os.Setenv(databasePrefixEnvKey, "databasePrefix")
+ defer os.Unsetenv(databasePrefixEnvKey)
+
+ os.Setenv(databaseTimeoutEnvKey, "1")
+ defer os.Unsetenv(databaseTimeoutEnvKey)
+
+ os.Setenv(agentWebhookEnvKey, "agentWebhook")
+ defer os.Unsetenv(agentWebhookEnvKey)
+
+ os.Setenv(agentDefaultLabelEnvKey, "agentDefaultLabel")
+ defer os.Unsetenv(agentDefaultLabelEnvKey)
+
+ os.Setenv(agentLogLevelEnvKey, "DEBUG")
+ defer os.Unsetenv(agentLogLevelEnvKey)
+
+ os.Setenv(agentHTTPResolverEnvKey, "agentHTTPResolver")
+ defer os.Unsetenv(agentHTTPResolverEnvKey)
+
+ os.Setenv(agentOutboundTransportEnvKey, "agentOutboundTransport")
+ defer os.Unsetenv(agentOutboundTransportEnvKey)
+
+ os.Setenv(agentTLSCertFileEnvKey, "agentTLSCertFile")
+ defer os.Unsetenv(agentTLSCertFileEnvKey)
+
+ os.Setenv(agentTLSKeyFileEnvKey, "agentTLSKeyFile")
+ defer os.Unsetenv(agentTLSKeyFileEnvKey)
+
+ os.Setenv(agentInboundHostEnvKey, "agentInboundHost")
+ defer os.Unsetenv(agentInboundHostEnvKey)
+
+ os.Setenv(agentInboundHostExternalEnvKey, "agentInboundHostExternal")
+ defer os.Unsetenv(agentInboundHostExternalEnvKey)
+
+ os.Setenv(agentWebSocketReadLimitEnvKey, "0")
+ defer os.Unsetenv(agentWebSocketReadLimitEnvKey)
+
+ os.Setenv(agentAutoAcceptEnvKey, "true")
+ defer os.Unsetenv(agentAutoAcceptEnvKey)
+
+ os.Setenv(agentTransportReturnRouteEnvKey, "agentTransportReturnRoute")
+ defer os.Unsetenv(agentTransportReturnRouteEnvKey)
+
+ os.Setenv(agentAutoExecuteRFC0593EnvKey, "true")
+ defer os.Unsetenv(agentAutoExecuteRFC0593EnvKey)
+
+ os.Setenv(agentContextProviderEnvKey, "agentContextProvider")
+ defer os.Unsetenv(agentContextProviderEnvKey)
+
+ os.Setenv(agentKeyTypeEnvKey, "agentKeyType")
+ defer os.Unsetenv(agentKeyTypeEnvKey)
+
+ os.Setenv(agentKeyAgreementTypeEnvKey, "agentKeyAgreementType")
+ defer os.Unsetenv(agentKeyAgreementTypeEnvKey)
+
+ os.Setenv(agentMediaTypeProfilesEnvKey, "agentMediaTypeProfiles")
+ defer os.Unsetenv(agentMediaTypeProfilesEnvKey)
+
+ parameters, err := NewAgentParameters(&mockServer{}, nil)
+
+ require.Nil(t, err)
+ require.Equal(t, spi.DEBUG, log.GetLevel(""))
+ require.Equal(t, "agentHost", parameters.host)
+ require.Equal(t, "agentToken", parameters.token)
+ require.Equal(t, "agentInboundHost", parameters.inboundHostInternals[0])
+ require.Equal(t, "agentInboundHostExternal", parameters.inboundHostExternals[0])
+ require.Equal(t, int64(0), parameters.websocketReadLimit)
+ require.Equal(t, "databaseType", parameters.dbParam.dbType)
+ require.Equal(t, "databasePrefix", parameters.dbParam.prefix)
+ require.Equal(t, uint64(1), parameters.dbParam.timeout)
+ require.Equal(t, "agentDefaultLabel", parameters.defaultLabel)
+ require.Equal(t, true, parameters.autoAccept)
+ require.Equal(t, "agentWebhook", parameters.webhookURLs[0])
+ require.Equal(t, "agentOutboundTransport", parameters.outboundTransports[0])
+ require.Equal(t, "agentTransportReturnRoute", parameters.transportReturnRoute)
+ require.Equal(t, "agentContextProvider", parameters.contextProviderURLs[0])
+ require.Equal(t, true, parameters.autoExecuteRFC0593)
+ require.Equal(t, "agentTLSCertFile", parameters.tlsCertFile)
+ require.Equal(t, "agentTLSKeyFile", parameters.tlsKeyFile)
+ require.Equal(t, "agentKeyType", parameters.keyType)
+ require.Equal(t, "agentKeyAgreementType", parameters.keyAgreementType)
+ require.Equal(t, "agentMediaTypeProfiles", parameters.mediaTypeProfiles[0])
+}
+
func waitForServerToStart(t *testing.T, host, inboundHost string) {
if err := listenFor(host); err != nil {
t.Fatal(err)
From 7e6cf9acbc9edc2c281e085748712c55f591016f Mon Sep 17 00:00:00 2001
From: Firas Qutishat
Date: Thu, 28 Apr 2022 17:51:56 +0300
Subject: [PATCH 29/54] feat: add HealthCheck method to localkms (#3234)
Signed-off-by: Firas Qutishat
---
pkg/kms/localkms/localkms.go | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/pkg/kms/localkms/localkms.go b/pkg/kms/localkms/localkms.go
index bc2b1025b..edb1cd329 100644
--- a/pkg/kms/localkms/localkms.go
+++ b/pkg/kms/localkms/localkms.go
@@ -97,6 +97,11 @@ func NewWithPrefix(primaryKeyURI string, p kms.Provider, storePrefix string) (*L
nil
}
+// HealthCheck check kms.
+func (l *LocalKMS) HealthCheck() error {
+ return nil
+}
+
// Create a new key/keyset/key handle for the type kt
// Returns:
// - keyID of the handle
From 66cc046674a1afa013984971abff0bc42175737a Mon Sep 17 00:00:00 2001
From: Derek Trider
Date: Thu, 28 Apr 2022 17:17:18 -0400
Subject: [PATCH 30/54] test: Option to skip the
"TestProviderOpenStoreSetGetConfig" tests (#3235)
---
test/component/storage/storage.go | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/test/component/storage/storage.go b/test/component/storage/storage.go
index 8c8b343f1..9498dc3e4 100644
--- a/test/component/storage/storage.go
+++ b/test/component/storage/storage.go
@@ -27,6 +27,7 @@ type testOptions struct {
onlySkipTotalItemTestsThatDoNotSetStoreConfig bool
skipSortTests bool
onlySkipSortTestsThatDoNotSetStoreConfig bool
+ skipSetGetStoreConfigTests bool
}
// SkipIteratorTotalItemTests causes all checks of an iterator's TotalItems method to be skipped.
@@ -52,6 +53,13 @@ func SkipSortTests(onlySkipTestsThatDoNotSetStoreConfig bool) TestOption {
}
}
+// SkipOpenStoreSetGetStoreConfigTests causes the tests in TestProviderOpenStoreSetGetConfig to be skipped.
+func SkipOpenStoreSetGetStoreConfigTests() TestOption {
+ return func(opts *testOptions) {
+ opts.skipSetGetStoreConfigTests = true
+ }
+}
+
func getOptions(opts []TestOption) testOptions {
options := testOptions{}
@@ -75,7 +83,9 @@ func TestAll(t *testing.T, provider spi.Provider, opts ...TestOption) {
TestProviderGetOpenStores(t, provider)
})
t.Run("Provider: open store and set/get config", func(t *testing.T) {
- TestProviderOpenStoreSetGetConfig(t, provider)
+ if !options.skipSetGetStoreConfigTests {
+ TestProviderOpenStoreSetGetConfig(t, provider)
+ }
})
t.Run("Store", func(t *testing.T) {
t.Run("Put and Get", func(t *testing.T) {
From 9924a3ce0136179af05c49485cbacfcaa0b1e83d Mon Sep 17 00:00:00 2001
From: Derek Trider
Date: Thu, 5 May 2022 16:30:16 -0400
Subject: [PATCH 31/54] feat: Use new EDV add index endpoint when setting store
config (#3237)
Also updated TrustBloc EDV image used for tests and removed some out-of-date comments.
Signed-off-by: Derek Trider
---
cmd/aries-js-worker/go.sum | 3 +-
component/storage/edv/go.mod | 2 +-
component/storage/edv/go.sum | 2 +
component/storage/edv/models.go | 11 +++--
component/storage/edv/restclient.go | 26 +++++++++++
component/storage/edv/restprovider.go | 28 ++++--------
component/storage/edv/restprovider_test.go | 53 ++++++++++++++++++----
scripts/start_edv_test_docker_images.sh | 2 +-
8 files changed, 92 insertions(+), 35 deletions(-)
diff --git a/cmd/aries-js-worker/go.sum b/cmd/aries-js-worker/go.sum
index 95f53e3f4..59fafb599 100644
--- a/cmd/aries-js-worker/go.sum
+++ b/cmd/aries-js-worker/go.sum
@@ -182,8 +182,9 @@ github.com/hashicorp/vault/sdk v0.1.13/go.mod h1:B+hVj7TpuQY1Y/GPbCpffmgd+tSEwvh
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
-github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220322085443-50e8f9bd208b h1:tq8CYv5vCJBSG2CjWKNt4l1BzZVJUy+GGF4U80fJV8o=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220322085443-50e8f9bd208b/go.mod h1:HojN6OAh8ZtXBe5X2arcSOe1SLo5Dsjqto8ICjSLQ2g=
+github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220428211718-66cc046674a1 h1:vxZ0DlFNLjgxMdBESLZu895AsI1JWL2SJerphwIn8Po=
+github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220428211718-66cc046674a1/go.mod h1:lykx3N+GX+sAWSxO2Ycc4Dz+ynV9b0Fv4NdP+ms4Alc=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
diff --git a/component/storage/edv/go.mod b/component/storage/edv/go.mod
index 1a1dc38b8..5a4be2e86 100644
--- a/component/storage/edv/go.mod
+++ b/component/storage/edv/go.mod
@@ -14,7 +14,7 @@ require (
github.com/hyperledger/aries-framework-go v0.1.8-0.20220322085443-50e8f9bd208b
github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220322085443-50e8f9bd208b
github.com/hyperledger/aries-framework-go/spi v0.0.0-20220322085443-50e8f9bd208b
- github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220322085443-50e8f9bd208b
+ github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220428211718-66cc046674a1
github.com/stretchr/testify v1.7.0
)
diff --git a/component/storage/edv/go.sum b/component/storage/edv/go.sum
index 12b80c621..1fbe3f026 100644
--- a/component/storage/edv/go.sum
+++ b/component/storage/edv/go.sum
@@ -218,6 +218,8 @@ github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210820153043-8
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220217153004-1622c70e5767/go.mod h1:HojN6OAh8ZtXBe5X2arcSOe1SLo5Dsjqto8ICjSLQ2g=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220322085443-50e8f9bd208b h1:tq8CYv5vCJBSG2CjWKNt4l1BzZVJUy+GGF4U80fJV8o=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220322085443-50e8f9bd208b/go.mod h1:HojN6OAh8ZtXBe5X2arcSOe1SLo5Dsjqto8ICjSLQ2g=
+github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220428211718-66cc046674a1 h1:vxZ0DlFNLjgxMdBESLZu895AsI1JWL2SJerphwIn8Po=
+github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220428211718-66cc046674a1/go.mod h1:lykx3N+GX+sAWSxO2Ycc4Dz+ynV9b0Fv4NdP+ms4Alc=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
diff --git a/component/storage/edv/models.go b/component/storage/edv/models.go
index dfe5ac6bf..e69f48e44 100644
--- a/component/storage/edv/models.go
+++ b/component/storage/edv/models.go
@@ -52,8 +52,6 @@ type indexedAttribute struct {
}
// idTypePair represents an ID+Type pair.
-// TODO: #2262 This is a simplified version of the actual EDV query format, which is still not finalized
-// in the spec as of writing. See: https://github.com/decentralized-identity/confidential-storage/issues/34.
type idTypePair struct {
ID string `json:"id"`
Type string `json:"type"`
@@ -62,7 +60,6 @@ type idTypePair struct {
// nameAndValueQuery represents a name+value pair that can be used to query the encrypted indices for specific data.
// TODO: #2262 This is a simplified version of the actual EDV query format, which is still not finalized
// in the spec as of writing. See: https://github.com/decentralized-identity/confidential-storage/issues/34.
-// ReturnFullDocuments is currently non-standard and should only be used with an EDV server that supports it.
type nameAndValueQuery struct {
ReturnFullDocuments bool `json:"returnFullDocuments"`
Name string `json:"index"`
@@ -71,7 +68,6 @@ type nameAndValueQuery struct {
// hasQuery represents a simpler version of query above that matches all documents that are tagged with the index name
// specified in "has", regardless of index value.
-// ReturnFullDocuments is currently non-standard and should only be used with an EDV server that supports it.
type hasQuery struct {
ReturnFullDocuments bool `json:"returnFullDocuments"`
Has string `json:"has"`
@@ -85,9 +81,14 @@ const (
)
// vaultOperation represents an upsert or delete operation to be performed in a vault.
-// This is currently non-standard and should only be used with an EDV server that supports it.
type vaultOperation struct {
Operation string `json:"operation"` // Valid values: upsert,delete
DocumentID string `json:"id,omitempty"` // Only used if Operation=delete
EncryptedDocument json.RawMessage `json:"document,omitempty"` // Only used if Operation=upsert
}
+
+// indexOperation represents an operation to add, update or remove indexes.
+type indexOperation struct {
+ Operation string `json:"operation"`
+ AttributeNames []string `json:"attributeNames"`
+}
diff --git a/component/storage/edv/restclient.go b/component/storage/edv/restclient.go
index 883c52416..8ed3dbaac 100644
--- a/component/storage/edv/restclient.go
+++ b/component/storage/edv/restclient.go
@@ -230,6 +230,32 @@ func (c *restClient) deleteDocument(vaultID, docID string) error {
return fmt.Errorf(failResponseFromEDVServer, statusCode, respBytes)
}
+func (c *restClient) addIndex(vaultID string, attributeNames []string) error {
+ addIndexOperation := indexOperation{
+ Operation: "add",
+ AttributeNames: attributeNames,
+ }
+
+ jsonToSend, err := json.Marshal(addIndexOperation)
+ if err != nil {
+ return fmt.Errorf("failed to marshal index operation: %w", err)
+ }
+
+ endpoint := fmt.Sprintf("%s/%s/index", c.edvServerURL, url.PathEscape(vaultID))
+
+ statusCode, _, respBytes, err := c.sendHTTPRequest(http.MethodPost, endpoint, jsonToSend, c.headersFunc)
+ if err != nil {
+ return fmt.Errorf("send HTTP request: %w", err)
+ }
+
+ if statusCode == http.StatusOK {
+ return nil
+ }
+
+ return fmt.Errorf("the EDV server returned status code %d along with the following message: %s",
+ statusCode, respBytes)
+}
+
func (c *restClient) sendHTTPRequest(method, endpoint string, body []byte,
addHeadersFunc addHeaders) (int, http.Header, []byte, error) {
var req *http.Request
diff --git a/component/storage/edv/restprovider.go b/component/storage/edv/restprovider.go
index 42a81c5a4..b45f71620 100644
--- a/component/storage/edv/restprovider.go
+++ b/component/storage/edv/restprovider.go
@@ -139,10 +139,10 @@ func (r *RESTProvider) OpenStore(name string) (spi.Store, error) {
return openStore, nil
}
-// SetStoreConfig isn't needed for EDV storage, since indexes are managed by the server automatically based on the
-// tags used in values. This method simply stores the configuration in memory so that it can be retrieved later
-// via the GetStoreConfig method, which allows it to be more consistent with how other store implementations work.
-// TODO (#2492) Store store config in persistent EDV storage for true consistency with other store implementations.
+// SetStoreConfig asks the EDV server to add indexes for the tag names specified config.
+// Currently, it is only capable of adding indexes to whatever indexes already exist. No existing indexes will get
+// removed.
+// TODO (#3236): Make this method work in the manner specified by the interface docs.
func (r *RESTProvider) SetStoreConfig(name string, config spi.StoreConfiguration) error {
for _, tagName := range config.TagNames {
if strings.Contains(tagName, ":") {
@@ -152,26 +152,17 @@ func (r *RESTProvider) SetStoreConfig(name string, config spi.StoreConfiguration
name = strings.ToLower(name)
- openStore, ok := r.openStores[name]
+ _, ok := r.openStores[name]
if !ok {
return spi.ErrStoreNotFound
}
- openStore.config = config
-
- return nil
+ return r.restClient.addIndex(r.vaultID, config.TagNames)
}
-// GetStoreConfig returns the store configuration currently stored in memory.
-func (r *RESTProvider) GetStoreConfig(name string) (spi.StoreConfiguration, error) {
- name = strings.ToLower(name)
-
- openStore, ok := r.openStores[name]
- if !ok {
- return spi.StoreConfiguration{}, spi.ErrStoreNotFound
- }
-
- return openStore.config, nil
+// GetStoreConfig is not implemented. See #3236.
+func (r *RESTProvider) GetStoreConfig(string) (spi.StoreConfiguration, error) {
+ return spi.StoreConfiguration{}, errors.New("not implemented")
}
// GetOpenStores returns all currently open stores.
@@ -212,7 +203,6 @@ type restStore struct {
name string
formatter *EncryptedFormatter
restClient *restClient
- config spi.StoreConfiguration
returnFullDocumentsOnQuery bool
batchEndpointExtensionEnabled bool
close closer
diff --git a/component/storage/edv/restprovider_test.go b/component/storage/edv/restprovider_test.go
index 39af09be7..737064f17 100644
--- a/component/storage/edv/restprovider_test.go
+++ b/component/storage/edv/restprovider_test.go
@@ -51,29 +51,34 @@ func (m *failingDecrypter) Decrypt(*jose.JSONWebEncryption) ([]byte, error) {
}
func TestCommon(t *testing.T) {
+ commonTestOptions := []storagetest.TestOption{
+ storagetest.SkipSortTests(false),
+ storagetest.SkipOpenStoreSetGetStoreConfigTests(),
+ }
+
t.Run("With random document IDs", func(t *testing.T) {
t.Run("Without batch endpoint extension", func(t *testing.T) {
t.Run(`Without "return full documents from queries" extension`, func(t *testing.T) {
edvRESTProvider := createEDVRESTProvider(t, createValidEncryptedFormatter(t))
- storagetest.TestAll(t, edvRESTProvider, storagetest.SkipSortTests(false))
+ storagetest.TestAll(t, edvRESTProvider, commonTestOptions...)
})
t.Run(`With "return full documents from queries" extension`, func(t *testing.T) {
edvRESTProvider := createEDVRESTProvider(t, createValidEncryptedFormatter(t),
edv.WithFullDocumentsReturnedFromQueries())
- storagetest.TestAll(t, edvRESTProvider, storagetest.SkipSortTests(false))
+ storagetest.TestAll(t, edvRESTProvider, commonTestOptions...)
})
})
t.Run("With batch endpoint extension", func(t *testing.T) {
t.Run(`Without "return full documents from queries" extension`, func(t *testing.T) {
edvRESTProvider := createEDVRESTProvider(t, createValidEncryptedFormatter(t),
edv.WithBatchEndpointExtension())
- storagetest.TestAll(t, edvRESTProvider, storagetest.SkipSortTests(false))
+ storagetest.TestAll(t, edvRESTProvider, commonTestOptions...)
})
t.Run(`With "return full documents from queries" extension`, func(t *testing.T) {
edvRESTProvider := createEDVRESTProvider(t, createValidEncryptedFormatter(t),
edv.WithBatchEndpointExtension(),
edv.WithFullDocumentsReturnedFromQueries())
- storagetest.TestAll(t, edvRESTProvider, storagetest.SkipSortTests(false))
+ storagetest.TestAll(t, edvRESTProvider, commonTestOptions...)
})
})
})
@@ -82,13 +87,13 @@ func TestCommon(t *testing.T) {
t.Run(`Without "return full documents from queries" extension`, func(t *testing.T) {
edvRESTProvider := createEDVRESTProvider(t,
createValidEncryptedFormatter(t, edv.WithDeterministicDocumentIDs()))
- storagetest.TestAll(t, edvRESTProvider, storagetest.SkipSortTests(false))
+ storagetest.TestAll(t, edvRESTProvider, commonTestOptions...)
})
t.Run(`With "return full documents from queries" extension`, func(t *testing.T) {
edvRESTProvider := createEDVRESTProvider(t,
createValidEncryptedFormatter(t, edv.WithDeterministicDocumentIDs()),
edv.WithFullDocumentsReturnedFromQueries())
- storagetest.TestAll(t, edvRESTProvider, storagetest.SkipSortTests(false))
+ storagetest.TestAll(t, edvRESTProvider, commonTestOptions...)
})
})
t.Run("With batch endpoint extension", func(t *testing.T) {
@@ -96,19 +101,51 @@ func TestCommon(t *testing.T) {
edvRESTProvider := createEDVRESTProvider(t,
createValidEncryptedFormatter(t, edv.WithDeterministicDocumentIDs()),
edv.WithBatchEndpointExtension())
- storagetest.TestAll(t, edvRESTProvider, storagetest.SkipSortTests(false))
+ storagetest.TestAll(t, edvRESTProvider, commonTestOptions...)
})
t.Run(`With "return full documents from queries" extension`, func(t *testing.T) {
edvRESTProvider := createEDVRESTProvider(t,
createValidEncryptedFormatter(t, edv.WithDeterministicDocumentIDs()),
edv.WithBatchEndpointExtension(),
edv.WithFullDocumentsReturnedFromQueries())
- storagetest.TestAll(t, edvRESTProvider, storagetest.SkipSortTests(false))
+ storagetest.TestAll(t, edvRESTProvider, commonTestOptions...)
})
})
})
}
+func TestRESTProvider_SetStoreConfig(t *testing.T) {
+ t.Run("Unsupported protocol scheme", func(t *testing.T) {
+ edvRESTProvider := edv.NewRESTProvider("BadURL", "VaultID",
+ createValidEncryptedFormatter(t))
+
+ _, err := edvRESTProvider.OpenStore("TestStore")
+ require.NoError(t, err)
+
+ err = edvRESTProvider.SetStoreConfig("TestStore", spi.StoreConfiguration{})
+ require.EqualError(t, err, "send HTTP request: failed to send request: "+
+ `Post "BadURL/VaultID/index": unsupported protocol scheme ""`)
+ })
+ t.Run("Vault does not exist", func(t *testing.T) {
+ edvRESTProvider := edv.NewRESTProvider(testServerURL, "VaultID",
+ createValidEncryptedFormatter(t))
+
+ _, err := edvRESTProvider.OpenStore("TestStore")
+ require.NoError(t, err)
+
+ err = edvRESTProvider.SetStoreConfig("TestStore", spi.StoreConfiguration{})
+ require.EqualError(t, err, "the EDV server returned status code 400 along with the following "+
+ "message: Failed to add indexes to data vault VaultID: specified vault does not exist.")
+ })
+}
+
+func TestRESTProvider_GetStoreConfig(t *testing.T) {
+ edvRESTProvider := createEDVRESTProvider(t, createValidEncryptedFormatter(t))
+
+ _, err := edvRESTProvider.GetStoreConfig("StoreName")
+ require.EqualError(t, err, "not implemented")
+}
+
func TestRESTStore_Put(t *testing.T) {
t.Run("Fail to generate encrypted document ID and encrypted document bytes "+
"for vault operation (batch extension enabled)", func(t *testing.T) {
diff --git a/scripts/start_edv_test_docker_images.sh b/scripts/start_edv_test_docker_images.sh
index bf475efdb..4951376de 100755
--- a/scripts/start_edv_test_docker_images.sh
+++ b/scripts/start_edv_test_docker_images.sh
@@ -47,4 +47,4 @@ PWD=$(pwd)
configPath="$PWD"/scripts/couchdb-config/10-single-node.ini
docker run -p 5984:5984 -d --network AriesTestNetwork --name AriesCouchDBStorageTest -v "$configPath":/opt/couchdb/etc/local.d/config.ini -e COUCHDB_USER=admin -e COUCHDB_PASSWORD=password couchdb:3.1.0 >/dev/null
-docker run -p 8071:8071 -d --network AriesTestNetwork --name AriesEDVStorageTest ghcr.io/trustbloc-cicd/edv:0.1.7-snapshot-e86b12a start --host-url 0.0.0.0:8071 --database-prefix edv_db_ --database-type couchdb --database-url admin:password@AriesCouchDBStorageTest:5984 --with-extensions ReturnFullDocumentsOnQuery,Batch >/dev/null
+docker run -p 8071:8071 -d --network AriesTestNetwork --name AriesEDVStorageTest ghcr.io/trustbloc-cicd/edv:0.1.9-snapshot-325e1bd start --host-url 0.0.0.0:8071 --database-prefix edv_db_ --database-type couchdb --database-url admin:password@AriesCouchDBStorageTest:5984 --with-extensions ReturnFullDocumentsOnQuery,Batch >/dev/null
From 888a6f059b576499a23f476b5658dd3876e2008e Mon Sep 17 00:00:00 2001
From: Baha <29608896+Baha-sk@users.noreply.github.com>
Date: Mon, 9 May 2022 11:06:01 -0400
Subject: [PATCH 32/54] refactor: web-redirector with underscore (#3227)
Following this DIDcomm V2 spec udpate:
decentralized-identity/didcomm-messaging#363
web-redirect is now web_redirect.
Signed-off-by: Baha Shaaban
---
pkg/didcomm/common/model/ack.go | 2 +-
pkg/didcomm/protocol/issuecredential/models.go | 2 +-
pkg/didcomm/protocol/issuecredential/service.go | 2 +-
pkg/didcomm/protocol/presentproof/states.go | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/pkg/didcomm/common/model/ack.go b/pkg/didcomm/common/model/ack.go
index f549d3082..5fa790c3f 100644
--- a/pkg/didcomm/common/model/ack.go
+++ b/pkg/didcomm/common/model/ack.go
@@ -29,7 +29,7 @@ type Ack struct {
type AckV2 struct {
ID string `json:"id,omitempty"`
Type string `json:"type,omitempty"`
- WebRedirect interface{} `json:"web-redirect,omitempty"`
+ WebRedirect interface{} `json:"web_redirect,omitempty"`
Body AckV2Body `json:"body,omitempty"`
}
diff --git a/pkg/didcomm/protocol/issuecredential/models.go b/pkg/didcomm/protocol/issuecredential/models.go
index a9aa514b7..fa0b4cc30 100644
--- a/pkg/didcomm/protocol/issuecredential/models.go
+++ b/pkg/didcomm/protocol/issuecredential/models.go
@@ -164,7 +164,7 @@ type IssueCredentialV3 struct { //nolint: golint
ID string `json:"id,omitempty"`
Body IssueCredentialV3Body `json:"body,omitempty"`
// WebRedirect contains optional web redirect info to be sent to holder for redirect.
- WebRedirect *decorator.WebRedirect `json:"web-redirect,omitempty"`
+ WebRedirect *decorator.WebRedirect `json:"web_redirect,omitempty"`
// Attachments is an array of attachments containing the presentation in the requested format(s).
// Accepted values for the format attribute of each attachment are provided in the per format Attachment
// registry immediately below.
diff --git a/pkg/didcomm/protocol/issuecredential/service.go b/pkg/didcomm/protocol/issuecredential/service.go
index 7d89f5a62..37bf09b1b 100644
--- a/pkg/didcomm/protocol/issuecredential/service.go
+++ b/pkg/didcomm/protocol/issuecredential/service.go
@@ -909,7 +909,7 @@ func (s *Service) Accept(msgType string) bool {
func redirectInfo(msg service.DIDCommMsg) map[string]interface{} {
var redirectInfo struct {
WebRedirectV2 map[string]interface{} `json:"~web-redirect,omitempty"`
- WebRedirectV3 map[string]interface{} `json:"web-redirect,omitempty"`
+ WebRedirectV3 map[string]interface{} `json:"web_redirect,omitempty"`
}
err := msg.Decode(&redirectInfo)
diff --git a/pkg/didcomm/protocol/presentproof/states.go b/pkg/didcomm/protocol/presentproof/states.go
index 8c4b39b29..2d895710e 100644
--- a/pkg/didcomm/protocol/presentproof/states.go
+++ b/pkg/didcomm/protocol/presentproof/states.go
@@ -40,7 +40,7 @@ const (
codeInternalError = "internal"
codeRejectedError = "rejected"
webRedirect = "~web-redirect"
- webRedirectV2 = "web-redirect"
+ webRedirectV2 = "web_redirect"
)
// state action for network call.
From 261c3746d03eb182745a9df322e865f4a85281e9 Mon Sep 17 00:00:00 2001
From: Derek Trider
Date: Mon, 9 May 2022 14:18:17 -0400
Subject: [PATCH 33/54] feat: EDV provider - query for multiple tags using AND
operators (#3240)
Signed-off-by: Derek Trider
---
component/storage/edv/models.go | 21 +-
component/storage/edv/restclient.go | 106 ++----
component/storage/edv/restprovider.go | 103 +++---
component/storage/edv/restprovider_test.go | 355 ++++++++++++++++++++-
scripts/check_unit.sh | 10 +-
scripts/couchdb-config/10-single-node.ini | 14 -
scripts/start_edv_test_docker_images.sh | 14 +-
7 files changed, 446 insertions(+), 177 deletions(-)
delete mode 100644 scripts/couchdb-config/10-single-node.ini
diff --git a/component/storage/edv/models.go b/component/storage/edv/models.go
index e69f48e44..ae164fefb 100644
--- a/component/storage/edv/models.go
+++ b/component/storage/edv/models.go
@@ -57,20 +57,13 @@ type idTypePair struct {
Type string `json:"type"`
}
-// nameAndValueQuery represents a name+value pair that can be used to query the encrypted indices for specific data.
-// TODO: #2262 This is a simplified version of the actual EDV query format, which is still not finalized
-// in the spec as of writing. See: https://github.com/decentralized-identity/confidential-storage/issues/34.
-type nameAndValueQuery struct {
- ReturnFullDocuments bool `json:"returnFullDocuments"`
- Name string `json:"index"`
- Value string `json:"equals"`
-}
-
-// hasQuery represents a simpler version of query above that matches all documents that are tagged with the index name
-// specified in "has", regardless of index value.
-type hasQuery struct {
- ReturnFullDocuments bool `json:"returnFullDocuments"`
- Has string `json:"has"`
+// query represents a vault query.
+// See https://identity.foundation/edv-spec/#searching-encrypted-documents for more info.
+type query struct {
+ Index string `json:"index"`
+ Equals []map[string]string `json:"equals"`
+ Has string `json:"has"`
+ ReturnFullDocuments bool `json:"returnFullDocuments"`
}
const (
diff --git a/component/storage/edv/restclient.go b/component/storage/edv/restclient.go
index 8ed3dbaac..f678e294d 100644
--- a/component/storage/edv/restclient.go
+++ b/component/storage/edv/restclient.go
@@ -94,102 +94,58 @@ func (c *restClient) readDocument(vaultID, docID string) ([]byte, error) {
}
}
-// If value is blank, then we will do a "has" query instead which will match any documents tagged with the index name
-// regardless of value.
-func (c *restClient) queryVault(vaultID, name, value string) ([]string, error) {
- var jsonToSend []byte
-
- var err error
-
- if value == "" {
- query := hasQuery{
- Has: name,
- }
+// Queries the given vault and returns all documents that contain all the given tags. If a tag value is blank,
+// then it acts as a wildcard, where any tag value for the associated tag name will match.
+// If query.ReturnFullDocuments is false, then only the document locations will be returned via the first return value.
+// If query.ReturnFullDocuments is true, then the full documents will be returned via the second return value.
+func (c *restClient) query(vaultID string, tags []spi.Tag,
+ returnFullDocuments bool) ([]string, []encryptedDocument, error) {
+ subfilter := make(map[string]string, len(tags))
+
+ for _, tag := range tags {
+ subfilter[tag.Name] = tag.Value
+ }
- jsonToSend, err = json.Marshal(query)
- if err != nil {
- return nil, fmt.Errorf(`failed to marshal name-only "has" query: %w`, err)
- }
- } else {
- query := nameAndValueQuery{
- Name: name,
- Value: value,
- }
+ queryToSend := query{
+ Equals: []map[string]string{subfilter},
+ ReturnFullDocuments: returnFullDocuments,
+ }
- jsonToSend, err = json.Marshal(query)
- if err != nil {
- return nil, fmt.Errorf("failed to marshal name + value query: %w", err)
- }
+ jsonToSend, err := json.Marshal(queryToSend)
+ if err != nil {
+ return nil, nil, err
}
endpoint := fmt.Sprintf("%s/%s/query", c.edvServerURL, url.PathEscape(vaultID))
statusCode, _, respBytes, err := c.sendHTTPRequest(http.MethodPost, endpoint, jsonToSend, c.headersFunc)
if err != nil {
- return nil, fmt.Errorf(failSendPOSTRequest, err)
+ return nil, nil, fmt.Errorf(failSendPOSTRequest, err)
}
if statusCode == http.StatusOK {
- var docLocations []string
-
- err = json.Unmarshal(respBytes, &docLocations)
- if err != nil {
- return nil, fmt.Errorf("failed to unmarshal response bytes into document locations: %w", err)
- }
-
- return docLocations, nil
- }
-
- return nil, fmt.Errorf(failResponseFromEDVServer, statusCode, respBytes)
-}
-
-func (c *restClient) queryVaultForFullDocuments(vaultID, name, value string) ([]encryptedDocument, error) {
- var jsonToSend []byte
+ if returnFullDocuments {
+ var documents []encryptedDocument
- var err error
-
- if value == "" {
- query := hasQuery{
- ReturnFullDocuments: true,
- Has: name,
- }
+ err = json.Unmarshal(respBytes, &documents)
+ if err != nil {
+ return nil, nil, err
+ }
- jsonToSend, err = json.Marshal(query)
- if err != nil {
- return nil, fmt.Errorf(`failed to marshal name-only "has" query: %w`, err)
- }
- } else {
- query := nameAndValueQuery{
- ReturnFullDocuments: true,
- Name: name,
- Value: value,
+ return nil, documents, nil
}
- jsonToSend, err = json.Marshal(query)
- if err != nil {
- return nil, fmt.Errorf("failed to marshal name + value query: %w", err)
- }
- }
-
- endpoint := fmt.Sprintf("%s/%s/query", c.edvServerURL, url.PathEscape(vaultID))
-
- statusCode, _, respBytes, err := c.sendHTTPRequest(http.MethodPost, endpoint, jsonToSend, c.headersFunc)
- if err != nil {
- return nil, fmt.Errorf(failSendPOSTRequest, err)
- }
-
- if statusCode == http.StatusOK {
- var documents []encryptedDocument
+ var docURLs []string
- err = json.Unmarshal(respBytes, &documents)
+ err = json.Unmarshal(respBytes, &docURLs)
if err != nil {
- return nil, fmt.Errorf("failed to unmarshal encrypted documents: %w", err)
+ return nil, nil, err
}
- return documents, nil
+ return docURLs, nil, nil
}
- return nil, fmt.Errorf(failResponseFromEDVServer, statusCode, respBytes)
+ return nil, nil, fmt.Errorf(failResponseFromEDVServer, statusCode, respBytes)
}
func (c *restClient) batch(vaultID string, vaultOperations []vaultOperation) error {
diff --git a/component/storage/edv/restprovider.go b/component/storage/edv/restprovider.go
index b45f71620..5e6028175 100644
--- a/component/storage/edv/restprovider.go
+++ b/component/storage/edv/restprovider.go
@@ -19,8 +19,8 @@ import (
)
const (
- expressionTagNameOnlyLength = 1
- expressionTagNameAndValueLength = 2
+ criterionTagNameOnlyLength = 1
+ criterionTagNameAndValueLength = 2
invalidTagName = `"%s" is an invalid tag name since it contains one or more ':' characters`
invalidTagValue = `"%s" is an invalid tag value since it contains one or more ':' characters`
@@ -29,7 +29,7 @@ const (
var (
errEmptyKey = errors.New("key cannot be empty")
errInvalidQueryExpressionFormat = errors.New("invalid expression format. " +
- "it must be in the following format: TagName:TagValue")
+ "it must be in the following format: Criterion1&&Criterion2&&...CriterionN")
)
// RESTProviderOption allows for configuration of a RESTProvider.
@@ -322,7 +322,12 @@ func (r *restStore) GetBulk(keys ...string) ([][]byte, error) {
return values, nil
}
-// EDV doesn't support any of the current query options.
+// Expression format: Criterion1&&Criterion2&&...CriterionN.
+// The && characters indicate an AND operator. There must be at least one Criterion.
+// Each Criterion can be in one of either two formats: Either "TagName" or "TagName:TagValue" (both without quotes).
+// If only using TagName, then the tag value will be treated as a wildcard, so any data tagged with the given TagName
+// will be matched regardless of tag value.
+// Note that EDV doesn't support sorting or pagination.
// spi.WithPageSize will simply be ignored since it only relates to performance and not the actual end result.
// spi.WithInitialPageNum and spi.WithSortOrder will result in an error being returned since those options do
// affect the results that the Iterator returns.
@@ -332,18 +337,17 @@ func (r *restStore) Query(expression string, options ...spi.QueryOption) (spi.It
return nil, err
}
- expressionTagName, expressionTagValue, err := parseQueryExpression(expression)
+ parsedTags, err := parseQueryExpression(expression)
if err != nil {
return nil, fmt.Errorf("failed to parse query expression: %w", err)
}
- tag, err := r.formatter.formatTag(r.name,
- spi.Tag{Name: expressionTagName, Value: expressionTagValue})
+ tags, err := r.formatter.formatTags(r.name, parsedTags)
if err != nil {
- return nil, fmt.Errorf("failed to format tag for querying: %w", err)
+ return nil, fmt.Errorf("failed to format tags for querying: %w", err)
}
- return r.query(tag)
+ return r.query(tags)
}
func (r *restStore) Delete(key string) error {
@@ -577,8 +581,8 @@ func (r *restStore) getFullDocumentViaKeyTagQuery(key string) ([]byte, error) {
return nil, fmt.Errorf("failed to format key tag: %w", err)
}
- matchingDocuments, err := r.restClient.queryVaultForFullDocuments(r.vaultID,
- formattedKeyTag.Name, formattedKeyTag.Value)
+ _, matchingDocuments, err := r.restClient.query(r.vaultID,
+ []spi.Tag{{Name: formattedKeyTag.Name, Value: formattedKeyTag.Value}}, true)
if err != nil {
return nil, fmt.Errorf("failure while querying vault: %w", err)
}
@@ -598,45 +602,39 @@ func (r *restStore) getFullDocumentViaKeyTagQuery(key string) ([]byte, error) {
return encryptedDocumentBytes, nil
}
-func (r *restStore) query(encryptedIndexTag spi.Tag) (spi.Iterator, error) {
- if r.returnFullDocumentsOnQuery {
- documents, err :=
- r.restClient.queryVaultForFullDocuments(r.vaultID, encryptedIndexTag.Name, encryptedIndexTag.Value)
- if err != nil {
- return nil, fmt.Errorf("failure while querying vault: %w", err)
- }
-
- allDocumentsBytes := make([][]byte, len(documents))
+func (r *restStore) query(attributeTags []spi.Tag) (spi.Iterator, error) {
+ documentURLs, documents, err := r.restClient.query(r.vaultID, attributeTags, r.returnFullDocumentsOnQuery)
+ if err != nil {
+ return nil, fmt.Errorf("failure while querying vault: %w", err)
+ }
- for i, document := range documents {
- documentBytes, err := json.Marshal(document)
- if err != nil {
- return nil, fmt.Errorf("failed to marshal document into bytes: %w", err)
- }
+ if documentURLs != nil {
+ documentIDs := make([]string, len(documentURLs))
- allDocumentsBytes[i] = documentBytes
+ for i, documentURL := range documentURLs {
+ documentIDs[i] = getDocIDFromURL(documentURL)
}
return &restIterator{
vaultID: r.vaultID, restClient: r.restClient, formatter: r.formatter,
- documents: allDocumentsBytes,
+ documentIDs: documentIDs,
}, nil
}
- documentURLs, err := r.restClient.queryVault(r.vaultID, encryptedIndexTag.Name, encryptedIndexTag.Value)
- if err != nil {
- return nil, fmt.Errorf("failure while querying EDV server: %w", err)
- }
+ allDocumentsBytes := make([][]byte, len(documents))
- documentIDs := make([]string, len(documentURLs))
+ for i, document := range documents {
+ documentBytes, err := json.Marshal(document)
+ if err != nil {
+ return nil, fmt.Errorf("failed to marshal document into bytes: %w", err)
+ }
- for i, documentURL := range documentURLs {
- documentIDs[i] = getDocIDFromURL(documentURL)
+ allDocumentsBytes[i] = documentBytes
}
return &restIterator{
vaultID: r.vaultID, restClient: r.restClient, formatter: r.formatter,
- documentIDs: documentIDs,
+ documents: allDocumentsBytes,
}, nil
}
@@ -1016,7 +1014,8 @@ func (r *restStore) getDocumentIDViaKeyTagQuery(key string) (string, error) {
return "", fmt.Errorf("failed to format key tag: %w", err)
}
- matchingDocumentsURLs, err := r.restClient.queryVault(r.vaultID, formattedKeyTag.Name, formattedKeyTag.Value)
+ matchingDocumentsURLs, _, err := r.restClient.query(r.vaultID,
+ []spi.Tag{{Name: formattedKeyTag.Name, Value: formattedKeyTag.Value}}, false)
if err != nil {
return "", fmt.Errorf("failure while querying EDV server: %w", err)
}
@@ -1165,26 +1164,32 @@ func checkForUnsupportedQueryOptions(options []spi.QueryOption) error {
return nil
}
-func parseQueryExpression(expression string) (string, string, error) {
+func parseQueryExpression(expression string) ([]spi.Tag, error) {
if expression == "" {
- return "", "", errInvalidQueryExpressionFormat
+ return nil, errInvalidQueryExpressionFormat
}
- expressionSplit := strings.Split(expression, ":")
+ criteria := strings.Split(expression, "&&")
+
+ parsedTags := make([]spi.Tag, len(criteria))
- var expressionTagName, expressionTagValue string
+ for i, criterion := range criteria {
+ criterionSplitByTagNameAndValue := strings.Split(criterion, ":")
- switch len(expressionSplit) {
- case expressionTagNameOnlyLength:
- expressionTagName = expressionSplit[0]
- case expressionTagNameAndValueLength:
- expressionTagName = expressionSplit[0]
- expressionTagValue = expressionSplit[1]
- default:
- return "", "", errInvalidQueryExpressionFormat
+ switch len(criterionSplitByTagNameAndValue) {
+ case criterionTagNameOnlyLength:
+ parsedTags[i] = spi.Tag{Name: criterionSplitByTagNameAndValue[0]}
+ case criterionTagNameAndValueLength:
+ parsedTags[i] = spi.Tag{
+ Name: criterionSplitByTagNameAndValue[0],
+ Value: criterionSplitByTagNameAndValue[1],
+ }
+ default:
+ return nil, errInvalidQueryExpressionFormat
+ }
}
- return expressionTagName, expressionTagValue, nil
+ return parsedTags, nil
}
func getDocIDFromURL(docURL string) string {
diff --git a/component/storage/edv/restprovider_test.go b/component/storage/edv/restprovider_test.go
index 737064f17..dafe59c23 100644
--- a/component/storage/edv/restprovider_test.go
+++ b/component/storage/edv/restprovider_test.go
@@ -60,25 +60,25 @@ func TestCommon(t *testing.T) {
t.Run("Without batch endpoint extension", func(t *testing.T) {
t.Run(`Without "return full documents from queries" extension`, func(t *testing.T) {
edvRESTProvider := createEDVRESTProvider(t, createValidEncryptedFormatter(t))
- storagetest.TestAll(t, edvRESTProvider, commonTestOptions...)
+ runCommonTests(t, edvRESTProvider, commonTestOptions)
})
t.Run(`With "return full documents from queries" extension`, func(t *testing.T) {
edvRESTProvider := createEDVRESTProvider(t, createValidEncryptedFormatter(t),
edv.WithFullDocumentsReturnedFromQueries())
- storagetest.TestAll(t, edvRESTProvider, commonTestOptions...)
+ runCommonTests(t, edvRESTProvider, commonTestOptions)
})
})
t.Run("With batch endpoint extension", func(t *testing.T) {
t.Run(`Without "return full documents from queries" extension`, func(t *testing.T) {
edvRESTProvider := createEDVRESTProvider(t, createValidEncryptedFormatter(t),
edv.WithBatchEndpointExtension())
- storagetest.TestAll(t, edvRESTProvider, commonTestOptions...)
+ runCommonTests(t, edvRESTProvider, commonTestOptions)
})
t.Run(`With "return full documents from queries" extension`, func(t *testing.T) {
edvRESTProvider := createEDVRESTProvider(t, createValidEncryptedFormatter(t),
edv.WithBatchEndpointExtension(),
edv.WithFullDocumentsReturnedFromQueries())
- storagetest.TestAll(t, edvRESTProvider, commonTestOptions...)
+ runCommonTests(t, edvRESTProvider, commonTestOptions)
})
})
})
@@ -87,13 +87,13 @@ func TestCommon(t *testing.T) {
t.Run(`Without "return full documents from queries" extension`, func(t *testing.T) {
edvRESTProvider := createEDVRESTProvider(t,
createValidEncryptedFormatter(t, edv.WithDeterministicDocumentIDs()))
- storagetest.TestAll(t, edvRESTProvider, commonTestOptions...)
+ runCommonTests(t, edvRESTProvider, commonTestOptions)
})
t.Run(`With "return full documents from queries" extension`, func(t *testing.T) {
edvRESTProvider := createEDVRESTProvider(t,
createValidEncryptedFormatter(t, edv.WithDeterministicDocumentIDs()),
edv.WithFullDocumentsReturnedFromQueries())
- storagetest.TestAll(t, edvRESTProvider, commonTestOptions...)
+ runCommonTests(t, edvRESTProvider, commonTestOptions)
})
})
t.Run("With batch endpoint extension", func(t *testing.T) {
@@ -101,19 +101,24 @@ func TestCommon(t *testing.T) {
edvRESTProvider := createEDVRESTProvider(t,
createValidEncryptedFormatter(t, edv.WithDeterministicDocumentIDs()),
edv.WithBatchEndpointExtension())
- storagetest.TestAll(t, edvRESTProvider, commonTestOptions...)
+ runCommonTests(t, edvRESTProvider, commonTestOptions)
})
t.Run(`With "return full documents from queries" extension`, func(t *testing.T) {
edvRESTProvider := createEDVRESTProvider(t,
createValidEncryptedFormatter(t, edv.WithDeterministicDocumentIDs()),
edv.WithBatchEndpointExtension(),
edv.WithFullDocumentsReturnedFromQueries())
- storagetest.TestAll(t, edvRESTProvider, commonTestOptions...)
+ runCommonTests(t, edvRESTProvider, commonTestOptions)
})
})
})
}
+func runCommonTests(t *testing.T, provider spi.Provider, commonTestOptions []storagetest.TestOption) {
+ storagetest.TestAll(t, provider, commonTestOptions...)
+ testQueryWithMultipleTags(t, provider)
+}
+
func TestRESTProvider_SetStoreConfig(t *testing.T) {
t.Run("Unsupported protocol scheme", func(t *testing.T) {
edvRESTProvider := edv.NewRESTProvider("BadURL", "VaultID",
@@ -341,11 +346,11 @@ func TestRESTStore_Query(t *testing.T) {
require.NoError(t, err)
iterator, err := store.Query("TagName:TagValue")
- require.EqualError(t, err, `failed to format tag for querying: `+
+ require.EqualError(t, err, `failed to format tags for querying: failed to format tag: `+
`failed to compute MAC for tag name "TagName": bad key handle format`)
require.Nil(t, iterator)
})
- t.Run("Failure while querying EDV server", func(t *testing.T) {
+ t.Run("Failure while querying vault", func(t *testing.T) {
edvRESTProvider := edv.NewRESTProvider("InvalidURL", "InvalidVaultID",
createValidEncryptedFormatter(t))
@@ -353,7 +358,7 @@ func TestRESTStore_Query(t *testing.T) {
require.NoError(t, err)
iterator, err := store.Query("TagName:TagValue")
- require.EqualError(t, err, `failure while querying EDV server: failed to send POST request: `+
+ require.EqualError(t, err, `failure while querying vault: failed to send POST request: `+
`failed to send request: Post "InvalidURL/InvalidVaultID/query": unsupported protocol scheme ""`)
require.Nil(t, iterator)
})
@@ -585,6 +590,326 @@ func TestRESTStore_Batch(t *testing.T) {
})
}
+func testQueryWithMultipleTags(t *testing.T, provider spi.Provider) {
+ t.Helper()
+
+ defer func() {
+ require.NoError(t, provider.Close())
+ }()
+
+ keysToPut, valuesToPut, tagsToPut := getTestData()
+
+ storeName := randomStoreName()
+
+ store, err := provider.OpenStore(storeName)
+ require.NoError(t, err)
+
+ defer func() {
+ require.NoError(t, store.Close())
+ }()
+
+ putData(t, store, keysToPut, valuesToPut, tagsToPut)
+
+ t.Run("Both pairs are tag names + values - 3 values found", func(t *testing.T) {
+ queryExpressionsToTest := []string{
+ "Breed:GoldenRetriever&&NumLegs:4&&EarType:Floppy",
+ "NumLegs:4&&EarType:Floppy&&Breed:GoldenRetriever", // Should be equivalent to the above expression
+ }
+
+ expectedKeys := []string{keysToPut[0], keysToPut[3], keysToPut[4]}
+ expectedValues := [][]byte{valuesToPut[0], valuesToPut[3], valuesToPut[4]}
+ expectedTags := [][]spi.Tag{tagsToPut[0], tagsToPut[3], tagsToPut[4]}
+ expectedTotalItemsCount := 3
+
+ for _, queryExpressionToTest := range queryExpressionsToTest {
+ iterator, err := store.Query(queryExpressionToTest)
+ require.NoError(t, err)
+
+ verifyExpectedIterator(t, iterator, expectedKeys, expectedValues, expectedTags, expectedTotalItemsCount)
+ }
+ })
+ t.Run("Both pairs are tag names + values - 2 values found", func(t *testing.T) {
+ queryExpressionsToTest := []string{
+ "Breed:GoldenRetriever&&Personality:Calm",
+ "Personality:Calm&&Breed:GoldenRetriever", // Should be equivalent to the above expression
+ }
+
+ expectedKeys := []string{keysToPut[3], keysToPut[4]}
+ expectedValues := [][]byte{valuesToPut[3], valuesToPut[4]}
+ expectedTags := [][]spi.Tag{tagsToPut[3], tagsToPut[4]}
+ expectedTotalItemsCount := 2
+
+ for _, queryExpressionToTest := range queryExpressionsToTest {
+ iterator, err := store.Query(queryExpressionToTest)
+ require.NoError(t, err)
+
+ verifyExpectedIterator(t, iterator, expectedKeys, expectedValues, expectedTags, expectedTotalItemsCount)
+ }
+ })
+ t.Run("Both pairs are tag names + values - 1 value found", func(t *testing.T) {
+ queryExpressionsToTest := []string{
+ "Personality:Shy&&EarType:Pointy",
+ "EarType:Pointy&&Personality:Shy", // Should be equivalent to the above expression
+ }
+
+ expectedKeys := []string{keysToPut[1]}
+ expectedValues := [][]byte{valuesToPut[1]}
+ expectedTags := [][]spi.Tag{tagsToPut[1]}
+ expectedTotalItemsCount := 1
+
+ for _, queryExpressionToTest := range queryExpressionsToTest {
+ iterator, err := store.Query(queryExpressionToTest)
+ require.NoError(t, err)
+
+ verifyExpectedIterator(t, iterator, expectedKeys, expectedValues, expectedTags, expectedTotalItemsCount)
+ }
+ })
+ t.Run("Both pairs are tag names + values - 0 values found", func(t *testing.T) {
+ queryExpressionsToTest := []string{
+ "Personality:Crazy&&EarType:Pointy",
+ "EarType:Pointy&&Personality:Crazy", // Should be equivalent to the above expression
+ }
+
+ expectedTotalItemsCount := 0
+
+ for _, queryExpressionToTest := range queryExpressionsToTest {
+ iterator, err := store.Query(queryExpressionToTest)
+ require.NoError(t, err)
+
+ verifyExpectedIterator(t, iterator, nil, nil, nil, expectedTotalItemsCount)
+ }
+ })
+ t.Run("First pair is a tag name + value, second is a tag name only - 1 value found", func(t *testing.T) {
+ queryExpressionsToTest := []string{
+ "EarType:Pointy&&Nickname",
+ "Nickname&&EarType:Pointy", // Should be equivalent to the above expression
+ }
+
+ expectedKeys := []string{keysToPut[2]}
+ expectedValues := [][]byte{valuesToPut[2]}
+ expectedTags := [][]spi.Tag{tagsToPut[2]}
+ expectedTotalItemsCount := 1
+
+ for _, queryExpressionToTest := range queryExpressionsToTest {
+ iterator, err := store.Query(queryExpressionToTest)
+ require.NoError(t, err)
+
+ verifyExpectedIterator(t, iterator, expectedKeys, expectedValues, expectedTags, expectedTotalItemsCount)
+ }
+ })
+ t.Run("First pair is a tag name + value, second is a tag name only - 0 values found", func(t *testing.T) {
+ queryExpressionsToTest := []string{
+ "EarType:Pointy&&CoatType",
+ "CoatType&&EarType:Pointy", // Should be equivalent to the above expression
+ }
+
+ expectedTotalItemsCount := 0
+
+ for _, queryExpressionToTest := range queryExpressionsToTest {
+ iterator, err := store.Query(queryExpressionToTest)
+ require.NoError(t, err)
+
+ verifyExpectedIterator(t, iterator, nil, nil, nil, expectedTotalItemsCount)
+ }
+ })
+}
+
+func getTestData() (testKeys []string, testValues [][]byte, testTags [][]spi.Tag) {
+ testKeys = []string{
+ "Cassie",
+ "Luna",
+ "Miku",
+ "Amber",
+ "Brandy",
+ }
+
+ testValues = [][]byte{
+ []byte("is a big, young dog"),
+ []byte("is a small dog"),
+ []byte("is a fluffy dog (also small)"),
+ []byte("is a big, old dog"),
+ []byte("is a big dog of unknown age (but probably old)"),
+ }
+
+ testTags = [][]spi.Tag{
+ {
+ {Name: "Breed", Value: "GoldenRetriever"},
+ {Name: "Personality", Value: "Playful"},
+ {Name: "NumLegs", Value: "4"},
+ {Name: "EarType", Value: "Floppy"},
+ {Name: "Nickname", Value: "Miss"},
+ {Name: "Age", Value: "2"},
+ },
+ {
+ {Name: "Breed", Value: "Schweenie"},
+ {Name: "Personality", Value: "Shy"},
+ {Name: "NumLegs", Value: "4"},
+ {Name: "EarType", Value: "Pointy"},
+ {Name: "Age", Value: "1"},
+ },
+ {
+ {Name: "Breed", Value: "Pomchi"},
+ {Name: "Personality", Value: "Outgoing"},
+ {Name: "NumLegs", Value: "4"},
+ {Name: "EarType", Value: "Pointy"},
+ {Name: "Nickname", Value: "Fluffball"},
+ {Name: "Age", Value: "1"},
+ },
+ {
+ {Name: "Breed", Value: "GoldenRetriever"},
+ {Name: "Personality", Value: "Calm"},
+ {Name: "NumLegs", Value: "4"},
+ {Name: "EarType", Value: "Floppy"},
+ {Name: "Age", Value: "14"},
+ },
+ {
+ {Name: "Breed", Value: "GoldenRetriever"},
+ {Name: "Personality", Value: "Calm"},
+ {Name: "NumLegs", Value: "4"},
+ {Name: "EarType", Value: "Floppy"},
+ },
+ }
+
+ return testKeys, testValues, testTags
+}
+
+func putData(t *testing.T, store spi.Store, keys []string, values [][]byte, tags [][]spi.Tag) {
+ t.Helper()
+
+ for i := 0; i < len(keys); i++ {
+ err := store.Put(keys[i], values[i], tags[i]...)
+ require.NoError(t, err)
+ }
+}
+
+// expectedKeys, expectedValues, and expectedTags are with respect to the query's page settings.
+// Since Iterator.TotalItems' count is not affected by page settings, expectedTotalItemsCount must be passed in and
+// can't be determined by looking at the length of expectedKeys, expectedValues, nor expectedTags.
+func verifyExpectedIterator(t *testing.T, actualResultsItr spi.Iterator, //nolint:gocognit, gocyclo // test file
+ expectedKeys []string, expectedValues [][]byte, expectedTags [][]spi.Tag, expectedTotalItemsCount int) {
+ t.Helper()
+
+ if len(expectedValues) != len(expectedKeys) || len(expectedTags) != len(expectedKeys) {
+ require.FailNow(t,
+ "Invalid test case. Expected keys, values and tags slices must be the same length.")
+ }
+
+ t.Helper()
+
+ var dataChecklist struct {
+ keys []string
+ values [][]byte
+ tags [][]spi.Tag
+ received []bool
+ }
+
+ dataChecklist.keys = expectedKeys
+ dataChecklist.values = expectedValues
+ dataChecklist.tags = expectedTags
+ dataChecklist.received = make([]bool, len(expectedKeys))
+
+ moreResultsToCheck, err := actualResultsItr.Next()
+ require.NoError(t, err)
+
+ if !moreResultsToCheck && len(expectedKeys) != 0 {
+ require.FailNow(t, "query unexpectedly returned no results")
+ }
+
+ for moreResultsToCheck {
+ dataReceivedCount := 0
+
+ for _, received := range dataChecklist.received {
+ if received {
+ dataReceivedCount++
+ }
+ }
+
+ if dataReceivedCount == len(dataChecklist.received) {
+ require.FailNow(t, "iterator contains more results than expected")
+ }
+
+ var itrErr error
+ receivedKey, itrErr := actualResultsItr.Key()
+ require.NoError(t, itrErr)
+
+ receivedValue, itrErr := actualResultsItr.Value()
+ require.NoError(t, itrErr)
+
+ receivedTags, itrErr := actualResultsItr.Tags()
+ require.NoError(t, itrErr)
+
+ for i := 0; i < len(dataChecklist.keys); i++ {
+ if receivedKey == dataChecklist.keys[i] {
+ if string(receivedValue) == string(dataChecklist.values[i]) {
+ if equalTags(receivedTags, dataChecklist.tags[i]) {
+ dataChecklist.received[i] = true
+
+ break
+ }
+ }
+ }
+ }
+
+ moreResultsToCheck, err = actualResultsItr.Next()
+ require.NoError(t, err)
+ }
+
+ count, errTotalItems := actualResultsItr.TotalItems()
+ require.NoError(t, errTotalItems)
+ require.Equal(t, expectedTotalItemsCount, count)
+
+ err = actualResultsItr.Close()
+ require.NoError(t, err)
+
+ for _, received := range dataChecklist.received {
+ if !received {
+ require.FailNow(t, "received unexpected query results")
+ }
+ }
+}
+
+func equalTags(tags1, tags2 []spi.Tag) bool { //nolint:gocyclo // Test file
+ if len(tags1) != len(tags2) {
+ return false
+ }
+
+ matchedTags1 := make([]bool, len(tags1))
+ matchedTags2 := make([]bool, len(tags2))
+
+ for i, tag1 := range tags1 {
+ for j, tag2 := range tags2 {
+ if matchedTags2[j] {
+ continue // This tag has already found a match. Tags can only have one match!
+ }
+
+ if tag1.Name == tag2.Name && tag1.Value == tag2.Value {
+ matchedTags1[i] = true
+ matchedTags2[j] = true
+
+ break
+ }
+ }
+
+ if !matchedTags1[i] {
+ return false
+ }
+ }
+
+ for _, matchedTag := range matchedTags1 {
+ if !matchedTag {
+ return false
+ }
+ }
+
+ for _, matchedTag := range matchedTags2 {
+ if !matchedTag {
+ return false
+ }
+ }
+
+ return true
+}
+
func createEDVRESTProvider(t *testing.T, encryptedFormatter *edv.EncryptedFormatter,
options ...edv.RESTProviderOption) *edv.RESTProvider {
options = append(options,
@@ -624,7 +949,7 @@ func createEDVRESTProvider(t *testing.T, encryptedFormatter *edv.EncryptedFormat
err := backoff.Retry(func() error {
var err error
- // We defer outside of the function so we can read the response after we're out of this Retry function.
+ // We defer outside the function, so we can read the response after we're out of this Retry function.
response, err =
http.Post(testServerURL, "", //nolint: bodyclose // false positive
bytes.NewBuffer([]byte(testVaultConfig)))
@@ -637,7 +962,7 @@ func createEDVRESTProvider(t *testing.T, encryptedFormatter *edv.EncryptedFormat
}, backoff.WithMaxRetries(backoff.NewConstantBackOff(time.Second), 10))
require.NoError(t, err, `Failed to create data vault for testing. These unit tests `+
- `require specific CouchDB and EDV docker containers to be running first. `+
+ `require specific MongoDB and EDV docker containers to be running first. `+
`To run these unit tests, either execute the main unit test script by running `+
`"make unit-test" (without the quotes) from the root aries-framework-go directory, or, if you want to `+
`directly run only these EDV REST provider unit tests, run ". scripts/start_edv_test_docker_images.sh" `+
@@ -671,3 +996,7 @@ func getVaultIDFromURL(vaultURL string) string {
return vaultIDToRetrieve
}
+
+func randomStoreName() string {
+ return "store-" + uuid.New().String()
+}
diff --git a/scripts/check_unit.sh b/scripts/check_unit.sh
index bd380fee3..e5a28ef21 100755
--- a/scripts/check_unit.sh
+++ b/scripts/check_unit.sh
@@ -39,17 +39,17 @@ fi
# Any return status other than 0 or 1 is unusual and so we exit.
remove_docker_containers () {
DOCKER_KILL_EXIT_CODE=0
-docker kill AriesCouchDBStorageTest >/dev/null 2>&1 || DOCKER_KILL_EXIT_CODE=$?
+docker kill AriesMongoDBStorageTest >/dev/null 2>&1 || DOCKER_KILL_EXIT_CODE=$?
docker kill AriesEDVStorageTest >/dev/null 2>&1 || DOCKER_KILL_EXIT_CODE=$?
-check_exit_code $DOCKER_KILL_EXIT_CODE "docker kill AriesCouchDBStorageTest"
+check_exit_code $DOCKER_KILL_EXIT_CODE "docker kill AriesMongoDBStorageTest"
check_exit_code $DOCKER_KILL_EXIT_CODE "docker kill AriesEDVStorageTest"
DOCKER_RM_EXIT_CODE=0
-docker rm AriesCouchDBStorageTest >/dev/null 2>&1 || DOCKER_RM_EXIT_CODE=$?
+docker rm AriesMongoDBStorageTest >/dev/null 2>&1 || DOCKER_RM_EXIT_CODE=$?
docker rm AriesEDVStorageTest >/dev/null 2>&1 || DOCKER_RM_EXIT_CODE=$?
-check_exit_code $DOCKER_RM_EXIT_CODE "docker rm AriesCouchDBStorageTest"
+check_exit_code $DOCKER_RM_EXIT_CODE "docker rm AriesMongoDBStorageTest"
check_exit_code $DOCKER_RM_EXIT_CODE "docker rm AriesEDVStorageTest"
}
@@ -98,7 +98,7 @@ else
amend_coverage_file
-docker kill AriesCouchDBStorageTest >/dev/null
+docker kill AriesMongoDBStorageTest >/dev/null
docker kill AriesEDVStorageTest >/dev/null
remove_docker_containers
fi
diff --git a/scripts/couchdb-config/10-single-node.ini b/scripts/couchdb-config/10-single-node.ini
deleted file mode 100644
index b3388d508..000000000
--- a/scripts/couchdb-config/10-single-node.ini
+++ /dev/null
@@ -1,14 +0,0 @@
-#
-# Copyright SecureKey Technologies Inc. All Rights Reserved.
-#
-# SPDX-License-Identifier: Apache-2.0
-#
-
-# Explicitly set single_node=true when not in cluster mode.
-# This ensures our single CouchDB node creates all system databases for our tests, including _users.
-# References:
-# - https://docs.couchdb.org/en/3.1.0/config/couchdb.html#couchdb/single_node
-# - https://github.com/apache/couchdb-docker#no-system-databases-until-the-installation-is-finalized
-# - https://github.com/apache/couchdb-docker/issues/54#issuecomment-643818998
-[couchdb]
-single_node=true
diff --git a/scripts/start_edv_test_docker_images.sh b/scripts/start_edv_test_docker_images.sh
index 4951376de..18cd7abe4 100755
--- a/scripts/start_edv_test_docker_images.sh
+++ b/scripts/start_edv_test_docker_images.sh
@@ -23,17 +23,17 @@ fi
# Any return status other than 0 or 1 is unusual and so we exit.
remove_docker_containers () {
DOCKER_KILL_EXIT_CODE=0
-docker kill AriesCouchDBStorageTest >/dev/null 2>&1 || DOCKER_KILL_EXIT_CODE=$?
+docker kill AriesMongoDBStorageTest >/dev/null 2>&1 || DOCKER_KILL_EXIT_CODE=$?
docker kill AriesEDVStorageTest >/dev/null 2>&1 || DOCKER_KILL_EXIT_CODE=$?
-check_exit_code $DOCKER_KILL_EXIT_CODE "docker kill AriesCouchDBStorageTest"
+check_exit_code $DOCKER_KILL_EXIT_CODE "docker kill AriesMongoDBStorageTest"
check_exit_code $DOCKER_KILL_EXIT_CODE "docker kill AriesEDVStorageTest"
DOCKER_RM_EXIT_CODE=0
-docker rm AriesCouchDBStorageTest >/dev/null 2>&1 || DOCKER_RM_EXIT_CODE=$?
+docker rm AriesMongoDBStorageTest >/dev/null 2>&1 || DOCKER_RM_EXIT_CODE=$?
docker rm AriesEDVStorageTest >/dev/null 2>&1 || DOCKER_RM_EXIT_CODE=$?
-check_exit_code $DOCKER_RM_EXIT_CODE "docker rm AriesCouchDBStorageTest"
+check_exit_code $DOCKER_RM_EXIT_CODE "docker rm AriesMongoDBStorageTest"
check_exit_code $DOCKER_RM_EXIT_CODE "docker rm AriesEDVStorageTest"
}
@@ -44,7 +44,7 @@ check_exit_code $DOCKER_CREATE_NETWORK_EXIT_CODE "docker network create AriesTes
remove_docker_containers
PWD=$(pwd)
-configPath="$PWD"/scripts/couchdb-config/10-single-node.ini
-docker run -p 5984:5984 -d --network AriesTestNetwork --name AriesCouchDBStorageTest -v "$configPath":/opt/couchdb/etc/local.d/config.ini -e COUCHDB_USER=admin -e COUCHDB_PASSWORD=password couchdb:3.1.0 >/dev/null
-docker run -p 8071:8071 -d --network AriesTestNetwork --name AriesEDVStorageTest ghcr.io/trustbloc-cicd/edv:0.1.9-snapshot-325e1bd start --host-url 0.0.0.0:8071 --database-prefix edv_db_ --database-type couchdb --database-url admin:password@AriesCouchDBStorageTest:5984 --with-extensions ReturnFullDocumentsOnQuery,Batch >/dev/null
+docker run -p 27017:27017 -d --network AriesTestNetwork --name AriesMongoDBStorageTest mongo:4.0.0 >/dev/null
+
+docker run -p 8071:8071 -d --network AriesTestNetwork --name AriesEDVStorageTest ghcr.io/trustbloc-cicd/edv:0.1.9-snapshot-fb17917 start --host-url 0.0.0.0:8071 --database-prefix edv_db_ --database-type mongodb --database-url mongodb://AriesMongoDBStorageTest:27017 --with-extensions Batch >/dev/null
From d5971cedf7bac70db39048faf96c087ba1fbcc40 Mon Sep 17 00:00:00 2001
From: Volodymyr Kubiv <62515092+vkubiv@users.noreply.github.com>
Date: Mon, 16 May 2022 15:25:45 +0300
Subject: [PATCH 34/54] feat: now CredentialParse can use a customized vc
schema. (#3241)
Signed-off-by: Volodymyr Kubiv
---
pkg/doc/verifiable/credential.go | 88 ++++++++++++++++---
pkg/doc/verifiable/credential_test.go | 24 ++++-
pkg/doc/verifiable/support_test.go | 3 +
.../credential_without_issuancedate.jsonld | 67 ++++++++++++++
4 files changed, 168 insertions(+), 14 deletions(-)
create mode 100644 pkg/doc/verifiable/testdata/credential_without_issuancedate.jsonld
diff --git a/pkg/doc/verifiable/credential.go b/pkg/doc/verifiable/credential.go
index d032b939b..e4e35d862 100644
--- a/pkg/doc/verifiable/credential.go
+++ b/pkg/doc/verifiable/credential.go
@@ -26,14 +26,18 @@ import (
var logger = log.New("aries-framework/doc/verifiable")
-// DefaultSchema describes default schema.
-const DefaultSchema = `{
+const (
+ schemaPropertyType = "type"
+ schemaPropertyCredentialSubject = "credentialSubject"
+ schemaPropertyIssuer = "issuer"
+ schemaPropertyIssuanceDate = "issuanceDate"
+)
+
+// DefaultSchemaTemplate describes default schema.
+const DefaultSchemaTemplate = `{
"required": [
- "@context",
- "type",
- "credentialSubject",
- "issuer",
- "issuanceDate"
+ "@context"
+ %s
],
"properties": {
"@context": {
@@ -574,6 +578,7 @@ type credentialOpts struct {
disabledProofCheck bool
strictValidation bool
ldpSuites []verifier.SignatureSuite
+ defaultSchema string
jsonldCredentialOpts
}
@@ -588,6 +593,13 @@ func WithDisabledProofCheck() CredentialOpt {
}
}
+// WithSchema option to set custom schema.
+func WithSchema(schema string) CredentialOpt {
+ return func(opts *credentialOpts) {
+ opts.defaultSchema = schema
+ }
+}
+
// WithNoCustomSchemaCheck option is for disabling of Credential Schemas download if defined
// in Verifiable Credential. Instead, the Verifiable Credential is checked against default Schema.
func WithNoCustomSchemaCheck() CredentialOpt {
@@ -1179,7 +1191,7 @@ func validateCredentialUsingJSONSchema(data []byte, schemas []TypedID, opts *cre
func getSchemaLoader(schemas []TypedID, opts *credentialOpts) (gojsonschema.JSONLoader, error) {
if opts.disabledCustomSchema {
- return defaultSchemaLoader(), nil
+ return defaultSchemaLoaderWithOpts(opts), nil
}
for _, schema := range schemas {
@@ -1197,11 +1209,67 @@ func getSchemaLoader(schemas []TypedID, opts *credentialOpts) (gojsonschema.JSON
}
// If no custom schema is chosen, use default one
- return defaultSchemaLoader(), nil
+ return defaultSchemaLoaderWithOpts(opts), nil
+}
+
+type schemaOpts struct {
+ disabledChecks []string
+}
+
+// SchemaOpt is create default schema options.
+type SchemaOpt func(*schemaOpts)
+
+// WithDisableRequiredField disabled check of required field in default schema.
+func WithDisableRequiredField(fieldName string) SchemaOpt {
+ return func(opts *schemaOpts) {
+ opts.disabledChecks = append(opts.disabledChecks, fieldName)
+ }
+}
+
+// JSONSchemaLoader creates default schema with the option to disable the check of specific properties.
+func JSONSchemaLoader(opts ...SchemaOpt) string {
+ defaultRequired := []string{
+ schemaPropertyType,
+ schemaPropertyCredentialSubject,
+ schemaPropertyIssuer,
+ schemaPropertyIssuanceDate,
+ }
+
+ dsOpts := &schemaOpts{}
+ for _, opt := range opts {
+ opt(dsOpts)
+ }
+
+ required := ""
+
+ for _, prop := range defaultRequired {
+ filterOut := false
+
+ for _, d := range dsOpts.disabledChecks {
+ if prop == d {
+ filterOut = true
+ break
+ }
+ }
+
+ if !filterOut {
+ required += fmt.Sprintf(",%q", prop)
+ }
+ }
+
+ return fmt.Sprintf(DefaultSchemaTemplate, required)
+}
+
+func defaultSchemaLoaderWithOpts(opts *credentialOpts) gojsonschema.JSONLoader {
+ if opts.defaultSchema != "" {
+ return gojsonschema.NewStringLoader(opts.defaultSchema)
+ }
+
+ return defaultSchemaLoader()
}
func defaultSchemaLoader() gojsonschema.JSONLoader {
- return gojsonschema.NewStringLoader(DefaultSchema)
+ return gojsonschema.NewStringLoader(JSONSchemaLoader())
}
func getJSONSchema(url string, opts *credentialOpts) ([]byte, error) {
diff --git a/pkg/doc/verifiable/credential_test.go b/pkg/doc/verifiable/credential_test.go
index 8c3658e6b..0642c443f 100644
--- a/pkg/doc/verifiable/credential_test.go
+++ b/pkg/doc/verifiable/credential_test.go
@@ -123,6 +123,22 @@ func TestParseCredential(t *testing.T) {
})
}
+func TestParseCredentialWithoutIssuanceDate(t *testing.T) {
+ t.Run("test creation of new Verifiable Credential with disabled issuance date check", func(t *testing.T) {
+ schema := JSONSchemaLoader(WithDisableRequiredField("issuanceDate"))
+
+ vc, err := parseTestCredential(t, []byte(credentialWithoutIssuanceDate), WithStrictValidation(),
+ WithSchema(schema))
+ require.NoError(t, err)
+ require.NotNil(t, vc)
+ })
+
+ t.Run("'issuanceDate is required' error", func(t *testing.T) {
+ _, err := parseTestCredential(t, []byte(credentialWithoutIssuanceDate), WithStrictValidation())
+ require.Error(t, err)
+ })
+}
+
func TestValidateVerCredContext(t *testing.T) {
t.Run("test verifiable credential with a single context", func(t *testing.T) {
var raw rawCredential
@@ -766,7 +782,7 @@ func TestWithDisabledProofCheck(t *testing.T) {
func TestWithCredentialSchemaLoader(t *testing.T) {
httpClient := &http.Client{}
- jsonSchemaLoader := gojsonschema.NewStringLoader(DefaultSchema)
+ jsonSchemaLoader := gojsonschema.NewStringLoader(JSONSchemaLoader())
cache := NewExpirableSchemaCache(100, 10*time.Minute)
credentialOpt := WithCredentialSchemaLoader(
@@ -877,7 +893,7 @@ func TestWithEmbeddedSignatureSuites(t *testing.T) {
func TestCustomCredentialJsonSchemaValidator2018(t *testing.T) {
testServer := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
rawMap := make(map[string]interface{})
- require.NoError(t, json.Unmarshal([]byte(DefaultSchema), &rawMap))
+ require.NoError(t, json.Unmarshal([]byte(JSONSchemaLoader()), &rawMap))
// extend default schema to require new referenceNumber field to be mandatory
required, success := rawMap["required"].([]interface{})
@@ -995,7 +1011,7 @@ func TestDownloadCustomSchema(t *testing.T) {
noCacheOpts := &credentialOpts{schemaLoader: newDefaultSchemaLoader()}
withCacheOpts := &credentialOpts{schemaLoader: &CredentialSchemaLoader{
schemaDownloadClient: httpClient,
- jsonLoader: gojsonschema.NewStringLoader(DefaultSchema),
+ jsonLoader: gojsonschema.NewStringLoader(JSONSchemaLoader()),
cache: NewExpirableSchemaCache(32*1024*1024, time.Hour),
}}
@@ -1037,7 +1053,7 @@ func TestDownloadCustomSchema(t *testing.T) {
// Check for cache expiration.
withCacheOpts = &credentialOpts{schemaLoader: &CredentialSchemaLoader{
schemaDownloadClient: httpClient,
- jsonLoader: gojsonschema.NewStringLoader(DefaultSchema),
+ jsonLoader: gojsonschema.NewStringLoader(JSONSchemaLoader()),
cache: NewExpirableSchemaCache(32*1024*1024, time.Second),
}}
loadsCount = 0
diff --git a/pkg/doc/verifiable/support_test.go b/pkg/doc/verifiable/support_test.go
index 0386150da..32d5cc8ea 100644
--- a/pkg/doc/verifiable/support_test.go
+++ b/pkg/doc/verifiable/support_test.go
@@ -32,6 +32,9 @@ import (
//go:embed testdata/valid_credential.jsonld
var validCredential string //nolint:gochecknoglobals
+//go:embed testdata/credential_without_issuancedate.jsonld
+var credentialWithoutIssuanceDate string //nolint:gochecknoglobals
+
func (rc *rawCredential) stringJSON(t *testing.T) string {
bytes, err := json.Marshal(rc)
require.NoError(t, err)
diff --git a/pkg/doc/verifiable/testdata/credential_without_issuancedate.jsonld b/pkg/doc/verifiable/testdata/credential_without_issuancedate.jsonld
new file mode 100644
index 000000000..7bf3e82f4
--- /dev/null
+++ b/pkg/doc/verifiable/testdata/credential_without_issuancedate.jsonld
@@ -0,0 +1,67 @@
+{
+ "@context": [
+ "https://www.w3.org/2018/credentials/v1",
+ "https://www.w3.org/2018/credentials/examples/v1",
+ "https://w3id.org/security/jws/v1",
+ "https://trustbloc.github.io/context/vc/examples-v1.jsonld",
+ "https://w3id.org/security/suites/ed25519-2020/v1"
+ ],
+ "id": "http://example.edu/credentials/1872",
+ "type": "VerifiableCredential",
+ "credentialSubject": {
+ "id": "did:example:ebfeb1f712ebc6f1c276e12ec21"
+ },
+ "issuer": {
+ "id": "did:example:76e12ec712ebc6f1c221ebfeb1f",
+ "name": "Example University",
+ "image": "data:image/png;base64,iVBOR"
+ },
+ "expirationDate": "2020-01-01T19:23:24Z",
+ "credentialStatus": {
+ "id": "https://example.edu/status/24",
+ "type": "CredentialStatusList2017"
+ },
+ "evidence": [
+ {
+ "id": "https://example.edu/evidence/f2aeec97-fc0d-42bf-8ca7-0548192d4231",
+ "type": [
+ "DocumentVerification"
+ ],
+ "verifier": "https://example.edu/issuers/14",
+ "evidenceDocument": "DriversLicense",
+ "subjectPresence": "Physical",
+ "documentPresence": "Physical"
+ },
+ {
+ "id": "https://example.edu/evidence/f2aeec97-fc0d-42bf-8ca7-0548192dxyzab",
+ "type": [
+ "SupportingActivity"
+ ],
+ "verifier": "https://example.edu/issuers/14",
+ "evidenceDocument": "Fluid Dynamics Focus",
+ "subjectPresence": "Digital",
+ "documentPresence": "Digital"
+ }
+ ],
+ "termsOfUse": [
+ {
+ "type": "IssuerPolicy",
+ "id": "http://example.com/policies/credential/4",
+ "profile": "http://example.com/profiles/credential",
+ "prohibition": [
+ {
+ "assigner": "https://example.edu/issuers/14",
+ "assignee": "AllVerifiers",
+ "target": "http://example.edu/credentials/3732",
+ "action": [
+ "Archival"
+ ]
+ }
+ ]
+ }
+ ],
+ "refreshService": {
+ "id": "https://example.edu/refresh/3732",
+ "type": "ManualRefreshService2018"
+ }
+}
From 0ba34929e05b0061b864a4d0c3c08f445ac53ab5 Mon Sep 17 00:00:00 2001
From: Bob Stasyszyn
Date: Mon, 16 May 2022 11:44:46 -0400
Subject: [PATCH 35/54] feat: Add multi-tag support to mem DB (#3242)
The mem DB now supports queries with multiple tags using the '&&' operator.
Signed-off-by: Bob Stasyszyn
---
component/storageutil/mem/mem.go | 75 ++++++++++----
component/storageutil/mem/mem_test.go | 136 ++++++++++++++++++++++++++
2 files changed, 193 insertions(+), 18 deletions(-)
diff --git a/component/storageutil/mem/mem.go b/component/storageutil/mem/mem.go
index c2ffebe69..d3724032d 100644
--- a/component/storageutil/mem/mem.go
+++ b/component/storageutil/mem/mem.go
@@ -255,6 +255,11 @@ func (m *memStore) GetBulk(keys ...string) ([][]byte, error) {
return values, nil
}
+type queryResult struct {
+ keys []string
+ dbEntries []dbEntry
+}
+
// Query returns all data that satisfies the expression. Expression format: TagName:TagValue.
// If TagValue is not provided, then all data associated with the TagName will be returned.
// For now, expression can only be a single tag Name + Value pair.
@@ -272,30 +277,32 @@ func (m *memStore) Query(expression string, options ...spi.QueryOption) (spi.Ite
return nil, errInvalidQueryExpressionFormat
}
- expressionSplit := strings.Split(expression, ":")
- switch len(expressionSplit) {
- case expressionTagNameOnlyLength:
- expressionTagName := expressionSplit[0]
-
- m.RLock()
- defer m.RUnlock()
+ queryResults := make(map[string]*queryResult)
- keys, dbEntries := m.getMatchingKeysAndDBEntries(expressionTagName, "")
+ for _, exp := range strings.Split(expression, "&&") {
+ expressionSplit := strings.Split(exp, ":")
+ switch len(expressionSplit) {
+ case expressionTagNameOnlyLength:
+ expressionTagName := expressionSplit[0]
- return &memIterator{keys: keys, dbEntries: dbEntries}, nil
- case expressionTagNameAndValueLength:
- expressionTagName := expressionSplit[0]
- expressionTagValue := expressionSplit[1]
+ keys, dbEntries := m.getMatchingKeysAndDBEntries(expressionTagName, "")
- m.RLock()
- defer m.RUnlock()
+ queryResults[expressionTagName] = &queryResult{keys: keys, dbEntries: dbEntries}
+ case expressionTagNameAndValueLength:
+ expressionTagName := expressionSplit[0]
+ expressionTagValue := expressionSplit[1]
- keys, dbEntries := m.getMatchingKeysAndDBEntries(expressionTagName, expressionTagValue)
+ keys, dbEntries := m.getMatchingKeysAndDBEntries(expressionTagName, expressionTagValue)
- return &memIterator{keys: keys, dbEntries: dbEntries}, nil
- default:
- return nil, errInvalidQueryExpressionFormat
+ queryResults[expressionTagName] = &queryResult{keys: keys, dbEntries: dbEntries}
+ default:
+ return nil, errInvalidQueryExpressionFormat
+ }
}
+
+ keys, dbEntries := commonDBEntries(queryResults)
+
+ return &memIterator{keys: keys, dbEntries: dbEntries}, nil
}
// Delete deletes the key + value pair (and all tags) associated with key.
@@ -365,6 +372,9 @@ func (m *memStore) getMatchingKeysAndDBEntries(tagName, tagValue string) ([]stri
var dbEntries []dbEntry
+ m.RLock()
+ defer m.RUnlock()
+
for key, dbEntry := range m.db {
for _, tag := range dbEntry.tags {
if tag.Name == tagName && (matchAnyValue || tag.Value == tagValue) {
@@ -462,3 +472,32 @@ func checkForUnsupportedQueryOptions(options []spi.QueryOption) error {
return nil
}
+
+// commonDBEntries returns the DB entries that appear in all the query results.
+func commonDBEntries(results map[string]*queryResult) ([]string, []dbEntry) {
+ numTags := len(results)
+ keyMap := make(map[string]int)
+ valueMap := make(map[string]dbEntry)
+
+ for _, result := range results {
+ for i, k := range result.keys {
+ keyMap[k]++
+
+ valueMap[k] = result.dbEntries[i]
+ }
+ }
+
+ var keys []string
+
+ var values []dbEntry
+
+ for k, n := range keyMap {
+ if n == numTags {
+ keys = append(keys, k)
+
+ values = append(values, valueMap[k])
+ }
+ }
+
+ return keys, values
+}
diff --git a/component/storageutil/mem/mem_test.go b/component/storageutil/mem/mem_test.go
index ac1646306..0a02849db 100644
--- a/component/storageutil/mem/mem_test.go
+++ b/component/storageutil/mem/mem_test.go
@@ -67,3 +67,139 @@ func TestProvider_Ping(t *testing.T) {
err := provider.Ping()
require.NoError(t, err)
}
+
+func TestMemStore_Query(t *testing.T) {
+ provider := mem.NewProvider()
+
+ store, err := provider.OpenStore("TestStore")
+ require.NoError(t, err)
+
+ const (
+ tagName1 = "TagName1"
+ tagName2 = "TagName2"
+ tagName3 = "TagName3"
+
+ tagValue1 = "TagValue1"
+ tagValue2 = "TagValue2"
+
+ key1 = "key1"
+ key2 = "key2"
+ key3 = "key3"
+ key4 = "key4"
+
+ value1 = "value1"
+ value2 = "value2"
+ value3 = "value3"
+ value4 = "value4"
+ )
+
+ require.NoError(t, store.Put(key1, []byte(value1),
+ spi.Tag{Name: tagName1, Value: tagValue1},
+ spi.Tag{Name: tagName2, Value: tagValue2},
+ spi.Tag{Name: tagName3}),
+ )
+
+ require.NoError(t, store.Put(key2, []byte(value2),
+ spi.Tag{Name: tagName1, Value: tagValue1},
+ spi.Tag{Name: tagName2, Value: tagValue2}),
+ )
+
+ require.NoError(t, store.Put(key3, []byte(value3),
+ spi.Tag{Name: tagName1, Value: tagValue1}),
+ )
+
+ require.NoError(t, store.Put(key4, []byte(value4),
+ spi.Tag{Name: tagName1, Value: "xxx"},
+ spi.Tag{Name: tagName3}),
+ )
+
+ t.Run("All tags -> one result", func(t *testing.T) {
+ iterator, err := store.Query("TagName1:TagValue1&&TagName2:TagValue2&&TagName3")
+ require.NoError(t, err)
+
+ ok, err := iterator.Next()
+ require.NoError(t, err)
+ require.True(t, ok)
+
+ key, err := iterator.Key()
+ require.NoError(t, err)
+ require.Equal(t, key1, key)
+
+ value, err := iterator.Value()
+ require.NoError(t, err)
+ require.Equal(t, value1, string(value))
+
+ ok, err = iterator.Next()
+ require.NoError(t, err)
+ require.False(t, ok)
+ })
+
+ t.Run("Tag2 -> 2 results", func(t *testing.T) {
+ iterator, err := store.Query("TagName2:TagValue2")
+ require.NoError(t, err)
+
+ ok, err := iterator.Next()
+ require.NoError(t, err)
+ require.True(t, ok)
+
+ key, err := iterator.Key()
+ require.NoError(t, err)
+ require.True(t, containsKey(key, key1, key2))
+
+ ok, err = iterator.Next()
+ require.NoError(t, err)
+ require.True(t, ok)
+
+ key, err = iterator.Key()
+ require.NoError(t, err)
+ require.True(t, containsKey(key, key1, key2))
+
+ ok, err = iterator.Next()
+ require.NoError(t, err)
+ require.False(t, ok)
+ })
+
+ t.Run("Tag3 -> 2 results", func(t *testing.T) {
+ iterator, err := store.Query("TagName3")
+ require.NoError(t, err)
+
+ ok, err := iterator.Next()
+ require.NoError(t, err)
+ require.True(t, ok)
+
+ key, err := iterator.Key()
+ require.NoError(t, err)
+ require.True(t, containsKey(key, key1, key4))
+
+ ok, err = iterator.Next()
+ require.NoError(t, err)
+ require.True(t, ok)
+
+ key, err = iterator.Key()
+ require.NoError(t, err)
+ require.True(t, containsKey(key, key1, key4))
+
+ ok, err = iterator.Next()
+ require.NoError(t, err)
+ require.False(t, ok)
+ })
+
+ t.Run("Invalid value for tag -> no results", func(t *testing.T) {
+ iterator, err := store.Query("TagName1:TagValueX")
+ require.NoError(t, err)
+
+ ok, err := iterator.Next()
+ require.NoError(t, err)
+ require.False(t, ok)
+ })
+}
+
+func containsKey(key string, expectedKey ...string) bool {
+ for _, k := range expectedKey {
+ if k == key {
+ return true
+ }
+ }
+
+ return false
+}
From 2d8ae9d24ae08e8227699a4bb33c24b610dbbcca Mon Sep 17 00:00:00 2001
From: Volodymyr Kubiv <62515092+vkubiv@users.noreply.github.com>
Date: Tue, 24 May 2022 21:15:34 +0300
Subject: [PATCH 36/54] feat: add support of multibase encoding for proofValue.
(#3244)
Signed-off-by: Volodymyr Kubiv
---
pkg/doc/did/doc.go | 7 ++--
pkg/doc/did/doc_test.go | 2 +-
pkg/doc/signature/proof/proof.go | 32 ++++++++++++++-
pkg/doc/signature/proof/proof_test.go | 41 ++++++++++++++++---
.../testdata/doc_with_many_proofs.jsonld | 2 +-
5 files changed, 72 insertions(+), 12 deletions(-)
diff --git a/pkg/doc/did/doc.go b/pkg/doc/did/doc.go
index 5406db69b..334a3dd6c 100644
--- a/pkg/doc/did/doc.go
+++ b/pkg/doc/did/doc.go
@@ -24,6 +24,7 @@ import (
"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"
)
@@ -597,9 +598,9 @@ func populateProofs(context, didID, baseURI string, rawProofs []interface{}) ([]
proofKey = jsonldSignatureValue
}
- proofValue, err := base64.RawURLEncoding.DecodeString(stringEntry(emap[proofKey]))
+ proofValue, err := sigproof.DecodeProofValue(stringEntry(emap[proofKey]), stringEntry(emap[jsonldType]))
if err != nil {
- return nil, err
+ return nil, errors.New("unsupported encoding")
}
nonce, err := base64.RawURLEncoding.DecodeString(stringEntry(emap[jsonldNonce]))
@@ -1438,7 +1439,7 @@ func populateRawProofs(context, didID, baseURI string, proofs []Proof) []interfa
jsonldType: p.Type,
jsonldCreated: p.Created,
jsonldCreator: creator,
- k: base64.RawURLEncoding.EncodeToString(p.ProofValue),
+ k: sigproof.EncodeProofValue(p.ProofValue, p.Type),
jsonldDomain: p.Domain,
jsonldNonce: base64.RawURLEncoding.EncodeToString(p.Nonce),
jsonldProofPurpose: p.ProofPurpose,
diff --git a/pkg/doc/did/doc_test.go b/pkg/doc/did/doc_test.go
index 775cac4b6..aabb06b5d 100644
--- a/pkg/doc/did/doc_test.go
+++ b/pkg/doc/did/doc_test.go
@@ -357,7 +357,7 @@ func TestInvalidEncodingInProof(t *testing.T) {
doc, err = populateProofs(c, "", "", rawProofs)
require.NotNil(t, err)
require.Nil(t, doc)
- require.Contains(t, err.Error(), "illegal base64 data")
+ require.Contains(t, err.Error(), "unsupported encoding")
}
}
diff --git a/pkg/doc/signature/proof/proof.go b/pkg/doc/signature/proof/proof.go
index cde8182b1..c2f0a0e9a 100644
--- a/pkg/doc/signature/proof/proof.go
+++ b/pkg/doc/signature/proof/proof.go
@@ -10,6 +10,8 @@ import (
"errors"
"fmt"
+ "github.com/multiformats/go-multibase"
+
"github.com/hyperledger/aries-framework-go/pkg/doc/util"
)
@@ -36,6 +38,8 @@ const (
jsonldChallenge = "challenge"
// jsonldCapabilityChain is a key for capabilityChain.
jsonldCapabilityChain = "capabilityChain"
+
+ ed25519Signature2020 = "Ed25519Signature2020"
)
// Proof is cryptographic proof of the integrity of the DID Document.
@@ -71,7 +75,7 @@ func NewProof(emap map[string]interface{}) (*Proof, error) {
)
if generalProof, ok := emap[jsonldProofValue]; ok {
- proofValue, err = decodeBase64(stringEntry(generalProof))
+ proofValue, err = DecodeProofValue(stringEntry(generalProof), stringEntry(emap[jsonldType]))
if err != nil {
return nil, err
}
@@ -143,6 +147,20 @@ func decodeBase64(s string) ([]byte, error) {
return nil, errors.New("unsupported encoding")
}
+// DecodeProofValue decodes proofValue basing on proof type.
+func DecodeProofValue(s, proofType string) ([]byte, error) {
+ if proofType == ed25519Signature2020 {
+ _, value, err := multibase.Decode(s)
+ if err == nil {
+ return value, nil
+ }
+
+ return nil, errors.New("unsupported encoding")
+ }
+
+ return decodeBase64(s)
+}
+
// stringEntry.
func stringEntry(entry interface{}) string {
if entry == nil {
@@ -170,7 +188,7 @@ func (p *Proof) JSONLdObject() map[string]interface{} { // nolint:gocyclo
}
if len(p.ProofValue) > 0 {
- emap[jsonldProofValue] = base64.RawURLEncoding.EncodeToString(p.ProofValue)
+ emap[jsonldProofValue] = EncodeProofValue(p.ProofValue, p.Type)
}
if len(p.JWS) > 0 {
@@ -200,6 +218,16 @@ func (p *Proof) JSONLdObject() map[string]interface{} { // nolint:gocyclo
return emap
}
+// EncodeProofValue decodes proofValue basing on proof type.
+func EncodeProofValue(proofValue []byte, proofType string) string {
+ if proofType == ed25519Signature2020 {
+ encoded, _ := multibase.Encode(multibase.Base58BTC, proofValue) //nolint: errcheck
+ return encoded
+ }
+
+ return base64.RawURLEncoding.EncodeToString(proofValue)
+}
+
// PublicKeyID provides ID of public key to be used to independently verify the proof.
// "verificationMethod" field is checked first. If not empty, its value is returned.
// Otherwise, "creator" field is returned if not empty. Otherwise, error is returned.
diff --git a/pkg/doc/signature/proof/proof_test.go b/pkg/doc/signature/proof/proof_test.go
index 0a841aa0c..e7e9fad62 100644
--- a/pkg/doc/signature/proof/proof_test.go
+++ b/pkg/doc/signature/proof/proof_test.go
@@ -10,12 +10,16 @@ import (
"testing"
"time"
+ "github.com/multiformats/go-multibase"
"github.com/stretchr/testify/require"
"github.com/hyperledger/aries-framework-go/pkg/doc/util"
)
-const proofValueBase64 = "6mdES87erjP5r1qCSRW__otj-A_Rj0YgRO7XU_0Amhwdfa7AAmtGUSFGflR_fZqPYrY9ceLRVQCJ49s0q7-LBA"
+const (
+ proofValueBase64 = "6mdES87erjP5r1qCSRW__otj-A_Rj0YgRO7XU_0Amhwdfa7AAmtGUSFGflR_fZqPYrY9ceLRVQCJ49s0q7-LBA"
+ proofValueMultibase = "z5gpJQZoaLUXevXk2mYYbQE9krfaJYBBwQcJhhAvX3zs6daJ2Eb6VJoU46WkUYN8R1vgX7o8ktuUkzpRJS5aJRQyh"
+)
func TestProof(t *testing.T) {
p, err := NewProof(map[string]interface{}{
@@ -44,6 +48,33 @@ func TestProof(t *testing.T) {
require.Equal(t, []byte(""), p.Nonce)
require.Equal(t, proofValueBytes, p.ProofValue)
+ // test proof with multibase encoding
+ p, err = NewProof(map[string]interface{}{
+ "type": "Ed25519Signature2020",
+ "creator": "didID",
+ "verificationMethod": "did:example:123456#key1",
+ "created": "2018-03-15T00:00:00Z",
+ "domain": "abc.com",
+ "nonce": "",
+ "proofValue": proofValueMultibase,
+ })
+ require.NoError(t, err)
+
+ // test proof
+ created, err = time.Parse(time.RFC3339, "2018-03-15T00:00:00Z")
+ require.NoError(t, err)
+
+ _, proofValueBytes, err = multibase.Decode(proofValueMultibase)
+ require.NoError(t, err)
+
+ require.Equal(t, "Ed25519Signature2020", p.Type)
+ require.Equal(t, "didID", p.Creator)
+ require.Equal(t, "did:example:123456#key1", p.VerificationMethod)
+ require.Equal(t, created, p.Created.Time)
+ require.Equal(t, "abc.com", p.Domain)
+ require.Equal(t, []byte(""), p.Nonce)
+ require.Equal(t, proofValueBytes, p.ProofValue)
+
// test created time with milliseconds section
p, err = NewProof(map[string]interface{}{
"type": "type",
@@ -164,7 +195,7 @@ func TestInvalidNonce(t *testing.T) {
func TestProof_JSONLdObject(t *testing.T) {
r := require.New(t)
- proofValueBytes, err := base64.RawURLEncoding.DecodeString(proofValueBase64)
+ _, proofValueBytes, err := multibase.Decode(proofValueMultibase)
r.NoError(err)
nonceBase64, err := base64.RawURLEncoding.DecodeString("abc")
@@ -174,7 +205,7 @@ func TestProof_JSONLdObject(t *testing.T) {
r.NoError(err)
p := &Proof{
- Type: "Ed25519Signature2018",
+ Type: "Ed25519Signature2020",
Created: util.NewTime(created),
Creator: "creator",
ProofValue: proofValueBytes,
@@ -186,10 +217,10 @@ func TestProof_JSONLdObject(t *testing.T) {
}
pJSONLd := p.JSONLdObject()
- r.Equal("Ed25519Signature2018", pJSONLd["type"])
+ r.Equal("Ed25519Signature2020", pJSONLd["type"])
r.Equal("2018-03-15T00:00:00Z", pJSONLd["created"])
r.Equal("creator", pJSONLd["creator"])
- r.Equal(proofValueBase64, pJSONLd["proofValue"])
+ r.Equal(proofValueMultibase, pJSONLd["proofValue"])
r.Equal("test.jws.value", pJSONLd["jws"])
r.Equal("assertionMethod", pJSONLd["proofPurpose"])
r.Equal("internal", pJSONLd["domain"])
diff --git a/pkg/doc/signature/suite/bbsblssignatureproof2020/testdata/doc_with_many_proofs.jsonld b/pkg/doc/signature/suite/bbsblssignatureproof2020/testdata/doc_with_many_proofs.jsonld
index 49236bb07..5e0f4ce12 100644
--- a/pkg/doc/signature/suite/bbsblssignatureproof2020/testdata/doc_with_many_proofs.jsonld
+++ b/pkg/doc/signature/suite/bbsblssignatureproof2020/testdata/doc_with_many_proofs.jsonld
@@ -37,7 +37,7 @@
"type": "BbsBlsSignature2020",
"created": "2020-12-06T19:23:10Z",
"proofPurpose": "assertionMethod",
- "proofValue": "jj3Xd3+KxmbQo85PFDjQJ7dAZlhj8A8W1Um8Vk7Xoiv6+jWRx5d8s0rgPk5dAXy6HwaJ4fQOde/MBb7E4QaGMlfK6y5eEKDUYzoGG0DScWIvaGcSZug6DwvWVXi+214P5MtlKnNwO6gJdemEgj8T/A==",
+ "proofValue": "mjj3Xd3+KxmbQo85PFDjQJ7dAZlhj8A8W1Um8Vk7Xoiv6+jWRx5d8s0rgPk5dAXy6HwaJ4fQOde/MBb7E4QaGMlfK6y5eEKDUYzoGG0DScWIvaGcSZug6DwvWVXi+214P5MtlKnNwO6gJdemEgj8T/A==",
"verificationMethod": "did:example:489398593#test"
},
{
From 18d510d849554e346b8283a4a752bc09c0979078 Mon Sep 17 00:00:00 2001
From: Baha <29608896+Baha-sk@users.noreply.github.com>
Date: Thu, 26 May 2022 16:52:58 -0400
Subject: [PATCH 37/54] refactor: set DIDcomm V1 VS V2 Endpoint support (#3239)
This change sets back the original DIDComm V1's Endpoint logic that was supperceded with the Endpoint struct update for DIDComm V2.
With this change, both ServiceEndpoint structures for V1 and V2 are not supported.
closes #3219
Signed-off-by: Baha Shaaban
---
pkg/client/connection/client.go | 29 +-
pkg/client/didexchange/client.go | 2 +
pkg/client/didexchange/client_test.go | 6 +-
pkg/client/messaging/client_test.go | 34 +--
pkg/client/outofband/client.go | 42 ++-
pkg/client/outofband/client_test.go | 75 +++---
pkg/common/model/endpoint.go | 174 +++++++++++-
pkg/common/model/endpoint_test.go | 133 +++++++++
.../command/didexchange/command_test.go | 6 +-
pkg/controller/command/messaging/command.go | 22 +-
.../command/messaging/command_test.go | 2 +-
.../rest/didexchange/operation_test.go | 6 +-
.../rest/messaging/operation_test.go | 2 +-
pkg/didcomm/common/middleware/middleware.go | 18 +-
pkg/didcomm/common/service/destination.go | 2 +
.../common/service/destination_default.go | 53 ++--
.../common/service/destination_interop.go | 3 +-
.../common/service/destination_test.go | 30 +--
pkg/didcomm/dispatcher/outbound/outbound.go | 94 +++++--
.../dispatcher/outbound/outbound_test.go | 75 +++---
.../packer/legacy/authcrypt/authcrypt_test.go | 3 +-
pkg/didcomm/packer/legacy/authcrypt/unpack.go | 7 +-
pkg/didcomm/protocol/didexchange/service.go | 119 +++++---
.../protocol/didexchange/service_test.go | 18 +-
pkg/didcomm/protocol/didexchange/states.go | 196 ++++++++++++--
.../protocol/didexchange/states_test.go | 254 +++++++++++-------
pkg/didcomm/protocol/mediator/service_test.go | 6 +-
pkg/didcomm/protocol/outofband/service.go | 67 ++++-
.../protocol/outofband/service_test.go | 68 +++--
pkg/didcomm/protocol/outofbandv2/service.go | 8 +-
.../protocol/outofbandv2/service_test.go | 15 +-
pkg/didcomm/transport/http/outbound.go | 7 +-
pkg/didcomm/transport/http/outbound_test.go | 2 +-
pkg/didcomm/transport/ws/outbound.go | 20 +-
pkg/didcomm/transport/ws/outbound_test.go | 11 +-
pkg/didcomm/transport/ws/pool_test.go | 4 +-
pkg/didcomm/transport/ws/support_test.go | 8 +-
pkg/doc/did/doc.go | 104 +++++--
pkg/doc/did/doc_test.go | 34 ++-
pkg/doc/did/helpers_test.go | 12 +-
pkg/doc/did/schema.go | 147 ++++++----
.../verifiable/credential_jwt_proof_test.go | 2 +-
pkg/framework/aries/framework_test.go | 6 +-
pkg/framework/context/context_test.go | 4 +-
pkg/mock/diddoc/mock_diddoc.go | 101 ++++---
pkg/mock/vdr/mock_registry.go | 12 +-
pkg/store/connection/connection_lookup.go | 2 +
pkg/store/did/didconnection_test.go | 10 +-
pkg/store/did/store_test.go | 2 +-
pkg/vdr/peer/creator.go | 90 ++++++-
pkg/vdr/peer/creator_test.go | 27 +-
pkg/vdr/verifiable_compat_test.go | 2 +-
test/bdd/agent/agent_sdk_steps.go | 1 +
test/bdd/cmd/sidetree/main.go | 3 +-
.../aries_didcommv2_mediator_e2e_sdk.feature | 1 +
.../features/waci_issuance_didcomm_v1.feature | 2 +-
test/bdd/fixtures/sidetree-mock/.env | 4 +-
.../didexchange_controller_steps.go | 6 +-
test/bdd/pkg/didresolver/didresolver_steps.go | 7 +-
test/bdd/pkg/sidetree/sidetree.go | 14 +-
.../waci_issuance_didcomm_v1_sdk_steps.go | 2 +-
61 files changed, 1618 insertions(+), 598 deletions(-)
create mode 100644 pkg/common/model/endpoint_test.go
diff --git a/pkg/client/connection/client.go b/pkg/client/connection/client.go
index 9cfb5885b..9f956604c 100644
--- a/pkg/client/connection/client.go
+++ b/pkg/client/connection/client.go
@@ -11,6 +11,7 @@ import (
"github.com/google/uuid"
+ "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/didcomm/common/middleware"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/peerdid"
@@ -22,6 +23,8 @@ import (
"github.com/hyperledger/aries-framework-go/spi/storage"
)
+var logger = log.New("aries-framework/pkg/client/connection")
+
type provider interface {
VDRegistry() vdr.Registry
DIDRotator() *middleware.DIDCommMessageMiddleware
@@ -80,6 +83,7 @@ func (c *Client) RotateDID(connectionID, signingKID string, opts ...RotateDIDOpt
}
// CreateConnectionV2 creates a DIDComm V2 connection with the given DID.
+//nolint:funlen
func (c *Client) CreateConnectionV2(myDID, theirDID string, opts ...CreateConnectionOption) (string, error) {
theirDocRes, err := c.vdr.Resolve(theirDID)
if err != nil {
@@ -105,16 +109,31 @@ func (c *Client) CreateConnectionV2(myDID, theirDID string, opts ...CreateConnec
connID := uuid.New().String()
+ uri, err := destination.ServiceEndpoint.URI()
+ if err != nil {
+ logger.Debugf("create destination from serviceEndpoint.URI() failed: %w, using value: %s", err, uri)
+ }
+
+ accept, err := destination.ServiceEndpoint.Accept()
+ if err != nil {
+ logger.Debugf("create destination from serviceEndpoint.Accept() failed: %w, using value %v", err, accept)
+ }
+
+ routingKeys, err := destination.ServiceEndpoint.RoutingKeys()
+ if err != nil {
+ logger.Debugf("create destination from serviceEndpoint.RoutingKeys() failed: %w, using value %v", err, routingKeys)
+ }
+
connRec := connection.Record{
ConnectionID: connID,
State: connection.StateNameCompleted,
TheirDID: theirDID,
MyDID: myDID,
- ServiceEndPoint: model.Endpoint{
- URI: destination.ServiceEndpoint.URI,
- Accept: destination.ServiceEndpoint.Accept,
- RoutingKeys: destination.ServiceEndpoint.RoutingKeys,
- },
+ ServiceEndPoint: model.NewDIDCommV2Endpoint([]model.DIDCommV2Endpoint{{
+ URI: uri,
+ Accept: accept,
+ RoutingKeys: routingKeys,
+ }}),
RecipientKeys: destination.RecipientKeys,
Namespace: connection.MyNSPrefix,
DIDCommVersion: service.V2,
diff --git a/pkg/client/didexchange/client.go b/pkg/client/didexchange/client.go
index 3f2140163..b39603e64 100644
--- a/pkg/client/didexchange/client.go
+++ b/pkg/client/didexchange/client.go
@@ -437,6 +437,8 @@ func (c *Client) CreateConnection(myDID string, theirDID *did.Doc, options ...Co
conn.ServiceEndPoint = destination.ServiceEndpoint
conn.RecipientKeys = destination.RecipientKeys
+ conn.RoutingKeys = destination.RoutingKeys
+ conn.MediaTypeProfiles = destination.MediaTypeProfiles
err = c.didexchangeSvc.CreateConnection(conn.Record, theirDID)
if err != nil {
diff --git a/pkg/client/didexchange/client_test.go b/pkg/client/didexchange/client_test.go
index 474ad7226..718b8a748 100644
--- a/pkg/client/didexchange/client_test.go
+++ b/pkg/client/didexchange/client_test.go
@@ -773,13 +773,13 @@ func TestClient_CreateConnection(t *testing.T) {
require.NoError(t, err)
// empty ServiceEndpoint to trigger CreateDestination error
- theirDID.Service[0].ServiceEndpoint.URI = ""
+ theirDID.Service[0].ServiceEndpoint = model.NewDIDCommV1Endpoint("")
_, err = c.CreateConnection(myDID.ID, theirDID,
WithTheirLabel(label), WithThreadID(threadID), WithParentThreadID(parentThreadID),
WithInvitationID(invitationID), WithInvitationDID(invitationDID), WithImplicit(implicit))
require.Contains(t, err.Error(), "createConnection: failed to create destination: "+
- "create destination: no service endpoint URI on didcomm service block in diddoc:")
+ "create destination: service endpoint URI on didcomm v1 service block in diddoc error:")
})
}
@@ -1516,7 +1516,7 @@ func newPeerDID(t *testing.T) *did.Doc {
d, err := ctx.VDRegistry().Create(
peer.DIDMethod, &did.Doc{Service: []did.Service{{
Type: "did-communication",
- ServiceEndpoint: model.Endpoint{URI: "http://agent.example.com/didcomm"},
+ ServiceEndpoint: model.NewDIDCommV1Endpoint("http://agent.example.com/didcomm"),
}}, VerificationMethod: []did.VerificationMethod{getSigningKey()}})
require.NoError(t, err)
diff --git a/pkg/client/messaging/client_test.go b/pkg/client/messaging/client_test.go
index f33e8bf2a..c93d99581 100644
--- a/pkg/client/messaging/client_test.go
+++ b/pkg/client/messaging/client_test.go
@@ -172,11 +172,9 @@ func TestCommand_Send(t *testing.T) { // nolint: gocognit, gocyclo
{
name: "send message to destination",
option: SendByDestination(&service.Destination{
- RecipientKeys: []string{"test"},
- ServiceEndpoint: model.Endpoint{
- URI: "sdfsdf",
- RoutingKeys: []string{"test"},
- },
+ RecipientKeys: []string{"test"},
+ ServiceEndpoint: model.NewDIDCommV1Endpoint("dfsdf"),
+ RoutingKeys: []string{"test"},
}),
},
}
@@ -269,11 +267,9 @@ func TestCommand_Send(t *testing.T) { // nolint: gocognit, gocyclo
name: "send message to destination",
option: []SendMessageOpions{
SendByDestination(&service.Destination{
- RecipientKeys: []string{"test"},
- ServiceEndpoint: model.Endpoint{
- URI: "sdfsdf",
- RoutingKeys: []string{"test"},
- },
+ RecipientKeys: []string{"test"},
+ ServiceEndpoint: model.NewDIDCommV1Endpoint("sdfsdf"),
+ RoutingKeys: []string{"test"},
}),
WaitForResponse(context.Background(), "sample-response-type"),
},
@@ -422,11 +418,9 @@ func TestCommand_Send(t *testing.T) { // nolint: gocognit, gocyclo
{
name: "send message to destination - failure 1",
option: SendByDestination(&service.Destination{
- RecipientKeys: []string{"test"},
- ServiceEndpoint: model.Endpoint{
- URI: "sdfsdf",
- RoutingKeys: []string{"test"},
- },
+ RecipientKeys: []string{"test"},
+ ServiceEndpoint: model.NewDIDCommV1Endpoint("sdfsdf"),
+ RoutingKeys: []string{"test"},
}),
messenger: &mocksvc.MockMessenger{ErrSendToDestination: fmt.Errorf("sample-err-01")},
errorMsg: "sample-err-01",
@@ -435,11 +429,9 @@ func TestCommand_Send(t *testing.T) { // nolint: gocognit, gocyclo
name: "send message to destination - failure 2",
kms: &mockkms.KeyManager{CrAndExportPubKeyErr: fmt.Errorf("sample-kmserr-01")},
option: SendByDestination(&service.Destination{
- RecipientKeys: []string{"test"},
- ServiceEndpoint: model.Endpoint{
- URI: "sdfsdf",
- RoutingKeys: []string{"test"},
- },
+ RecipientKeys: []string{"test"},
+ ServiceEndpoint: model.NewDIDCommV1Endpoint("sdfsdf"),
+ RoutingKeys: []string{"test"},
}),
errorMsg: "sample-kmserr-01",
},
@@ -454,7 +446,7 @@ func TestCommand_Send(t *testing.T) { // nolint: gocognit, gocyclo
option: SendByTheirDID("theirDID-001"),
vdr: &mockvdr.MockVDRegistry{
ResolveFunc: func(didID string, opts ...vdrapi.DIDMethodOption) (doc *did.DocResolution, e error) {
- return &did.DocResolution{DIDDocument: mockdiddoc.GetMockDIDDoc(t)}, nil
+ return &did.DocResolution{DIDDocument: mockdiddoc.GetMockDIDDoc(t, false)}, nil
},
},
errorMsg: "invalid payload data format",
diff --git a/pkg/client/outofband/client.go b/pkg/client/outofband/client.go
index 9a5fcbc10..0697bac1a 100644
--- a/pkg/client/outofband/client.go
+++ b/pkg/client/outofband/client.go
@@ -370,12 +370,13 @@ func validateServices(svcs ...interface{}) error {
// DidDocServiceFunc returns a function that returns a DID doc `service` entry.
// Used when no service entries are specified when creating messages.
-//nolint:funlen
+//nolint:funlen,gocyclo
func (c *Client) didServiceBlockFunc(p Provider) func(routerConnID string, accept []string) (*did.Service, error) {
return func(routerConnID string, accept []string) (*did.Service, error) {
var (
keyType kms.KeyType
didCommServiceType string
+ sp model.Endpoint
)
useDIDCommV2 := isDIDCommV2(accept)
@@ -384,9 +385,14 @@ func (c *Client) didServiceBlockFunc(p Provider) func(routerConnID string, accep
if useDIDCommV2 {
keyType = p.KeyAgreementType()
didCommServiceType = vdr.DIDCommV2ServiceType
+ sp = model.NewDIDCommV2Endpoint([]model.DIDCommV2Endpoint{{
+ URI: p.ServiceEndpoint(),
+ Accept: p.MediaTypeProfiles(),
+ }})
} else {
keyType = p.KeyType()
didCommServiceType = vdr.DIDCommServiceType
+ sp = model.NewDIDCommV1Endpoint(p.ServiceEndpoint())
}
if string(keyType) == "" {
@@ -418,7 +424,7 @@ func (c *Client) didServiceBlockFunc(p Provider) func(routerConnID string, accep
ID: uuid.New().String(),
Type: didCommServiceType,
RecipientKeys: []string{didKey},
- ServiceEndpoint: model.Endpoint{URI: p.ServiceEndpoint()},
+ ServiceEndpoint: sp,
}, nil
}
@@ -432,15 +438,33 @@ func (c *Client) didServiceBlockFunc(p Provider) func(routerConnID string, accep
return nil, fmt.Errorf("didServiceBlockFunc: create invitation - failed to add key to the router : %w", err)
}
- return &did.Service{
- ID: uuid.New().String(),
- Type: didCommServiceType,
- RecipientKeys: []string{didKey},
- ServiceEndpoint: model.Endpoint{
+ var svc *did.Service
+
+ if useDIDCommV2 {
+ sp = model.NewDIDCommV2Endpoint([]model.DIDCommV2Endpoint{{
URI: serviceEndpoint,
+ Accept: accept,
RoutingKeys: routingKeys,
- },
- }, nil
+ }})
+ svc = &did.Service{
+ ID: uuid.New().String(),
+ Type: didCommServiceType,
+ RecipientKeys: []string{didKey},
+ ServiceEndpoint: sp,
+ }
+ } else {
+ sp = model.NewDIDCommV1Endpoint(serviceEndpoint)
+ svc = &did.Service{
+ ID: uuid.New().String(),
+ Type: didCommServiceType,
+ RecipientKeys: []string{didKey},
+ ServiceEndpoint: sp,
+ RoutingKeys: routingKeys,
+ Accept: accept,
+ }
+ }
+
+ return svc, nil
}
}
diff --git a/pkg/client/outofband/client_test.go b/pkg/client/outofband/client_test.go
index 7fdaf492b..b59891024 100644
--- a/pkg/client/outofband/client_test.go
+++ b/pkg/client/outofband/client_test.go
@@ -75,15 +75,13 @@ func TestCreateInvitation(t *testing.T) {
})
t.Run("includes the diddoc Service block returned by provider", func(t *testing.T) {
expected := &did.Service{
- ID: uuid.New().String(),
- Type: uuid.New().String(),
- Priority: 0,
- RecipientKeys: []string{uuid.New().String()},
- ServiceEndpoint: commonmodel.Endpoint{
- URI: uuid.New().String(),
- RoutingKeys: []string{uuid.New().String()},
- },
- Properties: nil,
+ ID: uuid.New().String(),
+ Type: uuid.New().String(),
+ Priority: 0,
+ RecipientKeys: []string{uuid.New().String()},
+ ServiceEndpoint: commonmodel.NewDIDCommV1Endpoint(uuid.New().String()),
+ RoutingKeys: []string{uuid.New().String()},
+ Properties: nil,
}
c, err := New(withTestProvider())
require.NoError(t, err)
@@ -129,26 +127,31 @@ func TestCreateInvitation(t *testing.T) {
c.didDocSvcFunc = func(conn string, accept []string) (*did.Service, error) {
require.Equal(t, expectedConn, conn)
- var serviceType string
+ var svc *did.Service
if isDIDCommV2(accept) {
- serviceType = vdr.DIDCommV2ServiceType
+ svc = &did.Service{
+ ServiceEndpoint: commonmodel.NewDIDCommV2Endpoint([]commonmodel.DIDCommV2Endpoint{
+ {URI: expectedConn, Accept: accept},
+ }),
+ Type: vdr.DIDCommV2ServiceType,
+ }
} else {
- serviceType = vdr.DIDCommServiceType
+ svc = &did.Service{
+ ServiceEndpoint: commonmodel.NewDIDCommV1Endpoint(expectedConn),
+ Accept: accept,
+ Type: vdr.DIDCommServiceType,
+ }
}
- return &did.Service{
- ServiceEndpoint: commonmodel.Endpoint{
- URI: expectedConn,
- Accept: accept,
- },
- Type: serviceType,
- }, nil
+ return svc, nil
}
inv, err := c.CreateInvitation(nil, WithRouterConnections(expectedConn))
require.NoError(t, err)
- require.Equal(t, expectedConn, inv.Services[0].(*did.Service).ServiceEndpoint.URI)
+ uri, err := inv.Services[0].(*did.Service).ServiceEndpoint.URI()
+ require.NoError(t, err)
+ require.Equal(t, expectedConn, uri)
})
t.Run("WithGoal", func(t *testing.T) {
c, err := New(withTestProvider())
@@ -164,15 +167,13 @@ func TestCreateInvitation(t *testing.T) {
c, err := New(withTestProvider())
require.NoError(t, err)
expected := &did.Service{
- ID: uuid.New().String(),
- Type: uuid.New().String(),
- Priority: 0,
- RecipientKeys: []string{uuid.New().String()},
- ServiceEndpoint: commonmodel.Endpoint{
- URI: uuid.New().String(),
- RoutingKeys: []string{uuid.New().String()},
- },
- Properties: nil,
+ ID: uuid.New().String(),
+ Type: uuid.New().String(),
+ Priority: 0,
+ RecipientKeys: []string{uuid.New().String()},
+ ServiceEndpoint: commonmodel.NewDIDCommV1Endpoint(uuid.New().String()),
+ RoutingKeys: []string{uuid.New().String()},
+ Properties: nil,
}
inv, err := c.CreateInvitation([]interface{}{expected})
require.NoError(t, err)
@@ -193,15 +194,13 @@ func TestCreateInvitation(t *testing.T) {
require.NoError(t, err)
didRef := "did:example:234"
svc := &did.Service{
- ID: uuid.New().String(),
- Type: uuid.New().String(),
- Priority: 0,
- RecipientKeys: []string{uuid.New().String()},
- ServiceEndpoint: commonmodel.Endpoint{
- URI: uuid.New().String(),
- RoutingKeys: []string{uuid.New().String()},
- },
- Properties: nil,
+ ID: uuid.New().String(),
+ Type: uuid.New().String(),
+ Priority: 0,
+ RecipientKeys: []string{uuid.New().String()},
+ ServiceEndpoint: commonmodel.NewDIDCommV1Endpoint(uuid.New().String()),
+ RoutingKeys: []string{uuid.New().String()},
+ Properties: nil,
}
inv, err := c.CreateInvitation([]interface{}{svc, didRef})
require.NoError(t, err)
diff --git a/pkg/common/model/endpoint.go b/pkg/common/model/endpoint.go
index 9916c154e..8a074f703 100644
--- a/pkg/common/model/endpoint.go
+++ b/pkg/common/model/endpoint.go
@@ -6,8 +6,32 @@ SPDX-License-Identifier: Apache-2.0
package model
-// Endpoint contains endpoint specific content.
+import (
+ "encoding/json"
+ "fmt"
+ "net/url"
+)
+
+// ServiceEndpoint api for fetching ServiceEndpoint content based off of a DIDComm V1, V2 or DIDCore format.
+type ServiceEndpoint interface {
+ URI() (string, error)
+ Accept() ([]string, error)
+ RoutingKeys() ([]string, error)
+}
+
+// Endpoint contains endpoint specific content. Content of ServiceEndpoint api above will be used by priority:
+// 1- DIDcomm V2
+// 2- DIDComm V1
+// 3- DIDCore
+// To force lower priority endpoint content, avoid setting higher priority data during Unmarshal() execution.
type Endpoint struct {
+ rawDIDCommV2 []DIDCommV2Endpoint
+ rawDIDCommV1 string
+ rawObj interface{}
+}
+
+// DIDCommV2Endpoint contains ServiceEndpoint data specifically for DIDcommV2 and is wrapped in Endpoint as an array.
+type DIDCommV2Endpoint struct {
// URI contains the endpoint URI.
URI string `json:"uri"`
// Accept contains the MediaType profiles accepted by this endpoint.
@@ -15,3 +39,151 @@ type Endpoint struct {
// RoutingKeys contains the list of keys trusted as routing keys for the mediators/routers of this endpoint.
RoutingKeys []string `json:"routingKeys,omitempty"`
}
+
+// NewDIDCommV2Endpoint creates a DIDCommV2 endpoint with the given array of endpoints. At the time of writing this
+// comment, only the first endpoint is effective in the API. Additional logic is required to use a different index.
+func NewDIDCommV2Endpoint(endpoints []DIDCommV2Endpoint) Endpoint {
+ endpoint := Endpoint{rawDIDCommV2: []DIDCommV2Endpoint{}}
+ endpoint.rawDIDCommV2 = append(endpoint.rawDIDCommV2, endpoints...)
+
+ return endpoint
+}
+
+// NewDIDCommV1Endpoint creates a DIDCommV1 endpoint.
+func NewDIDCommV1Endpoint(uri string) Endpoint {
+ return Endpoint{
+ rawDIDCommV1: uri,
+ }
+}
+
+// NewDIDCoreEndpoint creates a generic DIDCore endpoint.
+func NewDIDCoreEndpoint(genericEndpoint interface{}) Endpoint {
+ return Endpoint{
+ rawObj: genericEndpoint,
+ }
+}
+
+// URI is the URI of a service endpoint.
+// It will return the value based on the underlying endpoint type in the following order:
+// 1- DIDComm V2 URI (currently the first element's URI). TODO enhance API to pass in an optional index.
+// 2- DIDComm V1 URI
+// 3- DIDCore's first element printed as string for now. (not used by AFGO at the time of this writing, but can be
+// enhanced if needed).
+func (s *Endpoint) URI() (string, error) {
+ // TODO for now, returning URI of first element. Add mechanism to fetch from appropriate index.
+ if len(s.rawDIDCommV2) > 0 {
+ return s.rawDIDCommV2[0].URI, nil
+ }
+
+ if s.rawDIDCommV1 != "" {
+ return stripQuotes(s.rawDIDCommV1), nil
+ }
+
+ if s.rawObj != nil {
+ switch o := s.rawObj.(type) {
+ case []string:
+ return o[0], nil
+ case [][]byte:
+ return string(o[0]), nil
+ case []interface{}:
+ return fmt.Sprintf("%s", o[0]), nil
+ default:
+ return "", fmt.Errorf("unrecognized DIDCore endpoint object %s", o)
+ }
+ }
+
+ return "", fmt.Errorf("endpoint URI not found")
+}
+
+// Accept is the DIDComm V2 Accept field of a service endpoint.
+func (s *Endpoint) Accept() ([]string, error) {
+ // TODO for now, returning Accept of first element. Add mechanism to fetch appropriate value.
+ if len(s.rawDIDCommV2) > 0 {
+ return s.rawDIDCommV2[0].Accept, nil
+ }
+
+ return nil, fmt.Errorf("endpoint Accept not found")
+}
+
+// RoutingKeys is the DIDComm V2 RoutingKeys field of a service endpoint.
+func (s *Endpoint) RoutingKeys() ([]string, error) {
+ // TODO for now, returning RoutingKeys of first element. Add mechanism to fetch appropriate value.
+ if len(s.rawDIDCommV2) > 0 {
+ return s.rawDIDCommV2[0].RoutingKeys, nil
+ }
+
+ return nil, fmt.Errorf("endpoint RoutingKeys not found")
+}
+
+// MarshalJSON marshals the content of Endpoint into a valid JSON []byte. Order of data is:
+// 1. DIDCommV2 format if found
+// 2. DIDCommV1 format if found
+// 3. DIDCore generic format if found
+// 4. JSON "Null" as fallback.
+func (s *Endpoint) MarshalJSON() ([]byte, error) {
+ if len(s.rawDIDCommV2) > 0 {
+ return json.Marshal(s.rawDIDCommV2)
+ }
+
+ if s.rawDIDCommV1 != "" {
+ return []byte(fmt.Sprintf("%q", s.rawDIDCommV1)), nil
+ }
+
+ if s.rawObj != nil {
+ return json.Marshal(s.rawObj)
+ }
+
+ // for existing connections, Endpoint can be empty, therefore don't fail marshalling here and
+ // return JSON null value instead.
+ return []byte("null"), nil
+}
+
+// UnmarshalJSON unmarshals data into Endpoint based on its format.
+func (s *Endpoint) UnmarshalJSON(data []byte) error {
+ s.rawDIDCommV2 = []DIDCommV2Endpoint{}
+ if err := json.Unmarshal(data, &s.rawDIDCommV2); err == nil {
+ s.rawDIDCommV1 = ""
+ s.rawObj = nil
+
+ return nil
+ }
+
+ if ok := isURL(string(data)); ok {
+ s.rawDIDCommV1 = stripQuotes(string(data))
+ s.rawDIDCommV2 = nil
+ s.rawObj = nil
+
+ return nil
+ }
+
+ if err := json.Unmarshal(data, &s.rawObj); err == nil {
+ s.rawDIDCommV1 = ""
+ s.rawDIDCommV2 = nil
+
+ return nil
+ }
+
+ return fmt.Errorf("endpoint data is not supported")
+}
+
+func isURL(str string) bool {
+ str = stripQuotes(str)
+
+ u, err := url.Parse(str)
+
+ return err == nil && u.Scheme != "" && u.Host != ""
+}
+
+func stripQuotes(str string) string {
+ if len(str) > 0 {
+ if str[0] == '"' {
+ str = str[1:]
+ }
+
+ if str[len(str)-1] == '"' {
+ str = str[:len(str)-1]
+ }
+ }
+
+ return str
+}
diff --git a/pkg/common/model/endpoint_test.go b/pkg/common/model/endpoint_test.go
new file mode 100644
index 000000000..f48924179
--- /dev/null
+++ b/pkg/common/model/endpoint_test.go
@@ -0,0 +1,133 @@
+/*
+Copyright SecureKey Technologies Inc. All Rights Reserved.
+
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package model
+
+import (
+ "fmt"
+ "testing"
+
+ "github.com/stretchr/testify/require"
+)
+
+func TestNewEndpoint(t *testing.T) {
+ uri := "uri"
+ accept := []string{"accept"}
+ routingkeys := []string{"key1"}
+
+ didCommV2Endpoint := Endpoint{
+ rawDIDCommV2: []DIDCommV2Endpoint{{
+ URI: uri,
+ Accept: accept,
+ RoutingKeys: routingkeys,
+ }},
+ }
+
+ ep := NewDIDCommV2Endpoint([]DIDCommV2Endpoint{{uri, accept, routingkeys}})
+ require.EqualValues(t, didCommV2Endpoint, ep)
+
+ didCommV1Endpoint := Endpoint{
+ rawDIDCommV1: uri,
+ }
+
+ ep = NewDIDCommV1Endpoint(uri)
+ require.EqualValues(t, didCommV1Endpoint, ep)
+
+ didCoreEndpoint := Endpoint{
+ rawObj: []string{uri, "uri2"},
+ }
+
+ ep = NewDIDCoreEndpoint([]string{uri, "uri2"})
+ require.EqualValues(t, didCoreEndpoint, ep)
+
+ ep = NewDIDCommV1Endpoint("")
+ require.EqualValues(t, Endpoint{}, ep)
+
+ m, err := ep.MarshalJSON()
+ require.NoError(t, err)
+ require.Equal(t, m, []byte("null"))
+
+ err = ep.UnmarshalJSON([]byte(""))
+ require.EqualError(t, err, "endpoint data is not supported")
+}
+
+func TestEndpoint_MarshalUnmarshalJSON(t *testing.T) {
+ testCases := []struct {
+ name string
+ endpoint interface{}
+ expectedValue interface{}
+ err error
+ }{
+ {
+ name: "marshal Endpoint for DIDComm V2",
+ endpoint: Endpoint{
+ rawDIDCommV2: []DIDCommV2Endpoint{{
+ URI: "https://agent.example.com/",
+ Accept: []string{"didcomm/v2"},
+ }},
+ },
+ expectedValue: []byte(`[{"uri":"https://agent.example.com/","accept":["didcomm/v2"]}]`),
+ },
+ {
+ name: "marshal Endpoint for DIDcomm V1",
+ endpoint: Endpoint{
+ rawDIDCommV1: "https://agent.example.com/",
+ },
+ expectedValue: []byte(fmt.Sprintf("%q", "https://agent.example.com/")),
+ err: nil,
+ },
+ {
+ name: "marshal random DIDCore Endpoint (neither DIDcomm V1 nor V2) as interface{}",
+ endpoint: Endpoint{
+ rawObj: []interface{}{"some random endpoint", "some other endpoint"},
+ },
+ expectedValue: []byte(`["some random endpoint","some other endpoint"]`),
+ err: nil,
+ },
+ }
+
+ for _, tc := range testCases {
+ ep, ok := tc.endpoint.(Endpoint)
+ if !ok {
+ continue
+ }
+
+ mep, err := ep.MarshalJSON()
+ require.NoError(t, err)
+ require.EqualValues(t, tc.expectedValue, mep)
+
+ newEP := Endpoint{}
+ err = newEP.UnmarshalJSON(mep)
+ require.NoError(t, err)
+ require.EqualValues(t, ep, newEP)
+
+ uri, err := newEP.URI()
+ require.NoError(t, err)
+
+ switch tc.name {
+ case "marshal Endpoint for DIDComm V2":
+ require.Equal(t, ep.rawDIDCommV2[0].URI, uri)
+
+ accept, e := newEP.Accept()
+ require.NoError(t, e)
+ require.Equal(t, ep.rawDIDCommV2[0].Accept, accept)
+
+ routingKeys, e := newEP.RoutingKeys()
+ require.NoError(t, e)
+ require.Equal(t, ep.rawDIDCommV2[0].RoutingKeys, routingKeys)
+ case "marshal Endpoint for DIDcomm V1":
+ require.Equal(t, ep.rawDIDCommV1, uri)
+
+ _, err = newEP.Accept()
+ require.EqualError(t, err, "endpoint Accept not found")
+
+ _, err = newEP.RoutingKeys()
+ require.EqualError(t, err, "endpoint RoutingKeys not found")
+ case "marshal random DIDCore Endpoint (neither DIDcomm V1 nor V2) as interface{}":
+ require.Equal(t, ep.rawObj.([]interface{})[0], uri)
+ }
+ }
+}
diff --git a/pkg/controller/command/didexchange/command_test.go b/pkg/controller/command/didexchange/command_test.go
index c8e60b305..f37dcab3c 100644
--- a/pkg/controller/command/didexchange/command_test.go
+++ b/pkg/controller/command/didexchange/command_test.go
@@ -989,10 +989,8 @@ func newPeerDID(t *testing.T) *did.Doc {
d, err := ctx.VDRegistry().Create(
peer.DIDMethod, &did.Doc{Service: []did.Service{{
- Type: vdr.DIDCommServiceType,
- ServiceEndpoint: model.Endpoint{
- URI: "http://agent.example.com/didcomm",
- },
+ Type: vdr.DIDCommServiceType,
+ ServiceEndpoint: model.NewDIDCommV1Endpoint("http://agent.example.com/didcomm"),
}}, VerificationMethod: []did.VerificationMethod{getSigningKey()}},
)
require.NoError(t, err)
diff --git a/pkg/controller/command/messaging/command.go b/pkg/controller/command/messaging/command.go
index 1e5a7779a..c364c82c1 100644
--- a/pkg/controller/command/messaging/command.go
+++ b/pkg/controller/command/messaging/command.go
@@ -186,13 +186,23 @@ func (o *Command) Send(rw io.Writer, req io.Reader) command.Error {
}
var destination *service.Destination
+
if request.ServiceEndpointDestination != nil {
- destination = &service.Destination{
- ServiceEndpoint: model.Endpoint{
- URI: request.ServiceEndpointDestination.ServiceEndpoint,
- RoutingKeys: request.ServiceEndpointDestination.RoutingKeys,
- },
- RecipientKeys: request.ServiceEndpointDestination.RecipientKeys,
+ routingKeys := request.ServiceEndpointDestination.RoutingKeys
+ if len(routingKeys) > 0 {
+ destination = &service.Destination{
+ ServiceEndpoint: model.NewDIDCommV1Endpoint(request.ServiceEndpointDestination.ServiceEndpoint),
+ RoutingKeys: routingKeys,
+ RecipientKeys: request.ServiceEndpointDestination.RecipientKeys,
+ }
+ } else {
+ destination = &service.Destination{
+ ServiceEndpoint: model.NewDIDCommV2Endpoint([]model.DIDCommV2Endpoint{{
+ URI: request.ServiceEndpointDestination.ServiceEndpoint,
+ RoutingKeys: routingKeys,
+ }}),
+ RecipientKeys: request.ServiceEndpointDestination.RecipientKeys,
+ }
}
}
diff --git a/pkg/controller/command/messaging/command_test.go b/pkg/controller/command/messaging/command_test.go
index 8fd1826b8..0b1aa51ff 100644
--- a/pkg/controller/command/messaging/command_test.go
+++ b/pkg/controller/command/messaging/command_test.go
@@ -561,7 +561,7 @@ func TestCommand_Send(t *testing.T) {
requestJSON: `{"message_body": "sample-input", "their_did": "theirDID-001"}`,
vdr: &mockvdr.MockVDRegistry{
ResolveFunc: func(didID string, opts ...vdrapi.DIDMethodOption) (doc *did.DocResolution, e error) {
- return &did.DocResolution{DIDDocument: mockdiddoc.GetMockDIDDoc(t)}, nil
+ return &did.DocResolution{DIDDocument: mockdiddoc.GetMockDIDDoc(t, false)}, nil
},
},
errorCode: SendMsgError,
diff --git a/pkg/controller/rest/didexchange/operation_test.go b/pkg/controller/rest/didexchange/operation_test.go
index b5c45feb8..e53ebfc3e 100644
--- a/pkg/controller/rest/didexchange/operation_test.go
+++ b/pkg/controller/rest/didexchange/operation_test.go
@@ -581,10 +581,8 @@ func newPeerDID(t *testing.T) *did.Doc {
d, err := ctx.VDRegistry().Create(
peer.DIDMethod, &did.Doc{Service: []did.Service{{
- Type: vdr.DIDCommServiceType,
- ServiceEndpoint: model.Endpoint{
- URI: "http://agent.example.com/didcomm",
- },
+ Type: vdr.DIDCommServiceType,
+ ServiceEndpoint: model.NewDIDCommV1Endpoint("http://agent.example.com/didcomm"),
}}, VerificationMethod: []did.VerificationMethod{getSigningKey()}},
)
require.NoError(t, err)
diff --git a/pkg/controller/rest/messaging/operation_test.go b/pkg/controller/rest/messaging/operation_test.go
index 12c7d2f87..ef865aa4f 100644
--- a/pkg/controller/rest/messaging/operation_test.go
+++ b/pkg/controller/rest/messaging/operation_test.go
@@ -583,7 +583,7 @@ func TestOperation_Send(t *testing.T) {
requestJSON: `{"message_body": "sample-input", "their_did": "theirDID-001"}`,
vdr: &mockvdr.MockVDRegistry{
ResolveFunc: func(didID string, opts ...vdrapi.DIDMethodOption) (*did.DocResolution, error) {
- return &did.DocResolution{DIDDocument: mockdiddoc.GetMockDIDDoc(t)}, nil
+ return &did.DocResolution{DIDDocument: mockdiddoc.GetMockDIDDoc(t, false)}, nil
},
},
httpErrCode: http.StatusInternalServerError,
diff --git a/pkg/didcomm/common/middleware/middleware.go b/pkg/didcomm/common/middleware/middleware.go
index 09d3e188e..7029e8702 100644
--- a/pkg/didcomm/common/middleware/middleware.go
+++ b/pkg/didcomm/common/middleware/middleware.go
@@ -217,16 +217,14 @@ func (h *DIDCommMessageMiddleware) handleInboundInvitationAcceptance(senderDID,
// if we created an invitation with this DID, and have no connection, we create a connection.
rec = &connection.Record{
- ConnectionID: uuid.New().String(),
- MyDID: recipientDID,
- TheirDID: senderDID,
- InvitationID: inv.ID,
- State: connection.StateNameCompleted,
- Namespace: connection.MyNSPrefix,
- ServiceEndPoint: model.Endpoint{
- Accept: h.mediaTypeProfiles,
- },
- DIDCommVersion: didcomm.V2,
+ ConnectionID: uuid.New().String(),
+ MyDID: recipientDID,
+ TheirDID: senderDID,
+ InvitationID: inv.ID,
+ State: connection.StateNameCompleted,
+ Namespace: connection.MyNSPrefix,
+ ServiceEndPoint: model.NewDIDCommV2Endpoint([]model.DIDCommV2Endpoint{{Accept: h.mediaTypeProfiles}}),
+ DIDCommVersion: didcomm.V2,
}
err = h.connStore.SaveConnectionRecord(rec)
diff --git a/pkg/didcomm/common/service/destination.go b/pkg/didcomm/common/service/destination.go
index 41d1a1725..68b1f8288 100644
--- a/pkg/didcomm/common/service/destination.go
+++ b/pkg/didcomm/common/service/destination.go
@@ -18,7 +18,9 @@ import (
type Destination struct {
RecipientKeys []string
ServiceEndpoint model.Endpoint
+ RoutingKeys []string
TransportReturnRoute string
+ MediaTypeProfiles []string
DIDDoc *did.Doc
}
diff --git a/pkg/didcomm/common/service/destination_default.go b/pkg/didcomm/common/service/destination_default.go
index 026b701f0..0e2260078 100644
--- a/pkg/didcomm/common/service/destination_default.go
+++ b/pkg/didcomm/common/service/destination_default.go
@@ -1,3 +1,4 @@
+//go:build !ACAPyInterop
// +build !ACAPyInterop
/*
@@ -18,8 +19,15 @@ import (
// CreateDestination makes a DIDComm Destination object from a DID Doc as per the DIDComm service conventions:
// https://github.com/hyperledger/aries-rfcs/blob/master/features/0067-didcomm-diddoc-conventions/README.md.
-//nolint:gocyclo,funlen
+//nolint:gocyclo,funlen,gocognit
func CreateDestination(didDoc *diddoc.Doc) (*Destination, error) {
+ var (
+ sp model.Endpoint
+ accept, routingKeys []string
+ uri string
+ err error
+ )
+
// try DIDComm V2 and use it if found, else use default DIDComm v1 bloc.
didCommService, ok := diddoc.LookupService(didDoc, didCommV2ServiceType)
if ok { //nolint:nestif
@@ -43,17 +51,32 @@ func CreateDestination(didDoc *diddoc.Doc) (*Destination, error) {
didCommService.RecipientKeys = recKeys
// if Accept is missing, ensure DIDCommV2 is at least added for packer selection based on MediaTypeProfile.
- if len(didCommService.ServiceEndpoint.Accept) == 0 {
- didCommService.ServiceEndpoint.Accept = []string{defaultDIDCommV2Profile}
+ if accept, err = didCommService.ServiceEndpoint.Accept(); len(accept) == 0 || err != nil {
+ accept = []string{defaultDIDCommV2Profile}
+ }
+
+ uri, err = didCommService.ServiceEndpoint.URI()
+ if err != nil { // uri is required.
+ return nil, fmt.Errorf("create destination: service endpoint URI for didcomm v2 service block "+
+ "error: %+v, %w", didDoc, err)
}
- } else {
+
+ routingKeys, err = didCommService.ServiceEndpoint.RoutingKeys()
+ if err != nil { // routingKeys can be optional.
+ routingKeys = nil
+ }
+
+ sp = model.NewDIDCommV2Endpoint([]model.DIDCommV2Endpoint{{URI: uri, Accept: accept, RoutingKeys: routingKeys}})
+ } else { // didcomm v1 service
didCommService, ok = diddoc.LookupService(didDoc, didCommServiceType)
if !ok {
return nil, fmt.Errorf("create destination: missing DID doc service")
}
- if didCommService.ServiceEndpoint.URI == "" {
- return nil, fmt.Errorf("create destination: no service endpoint URI on didcomm service block in diddoc: %+v", didDoc)
+ uri, err = didCommService.ServiceEndpoint.URI()
+ if err != nil { // uri is required.
+ return nil, fmt.Errorf("create destination: service endpoint URI on didcomm v1 service block "+
+ "in diddoc error: %+v, %w", didDoc, err)
}
if len(didCommService.RecipientKeys) == 0 {
@@ -68,18 +91,18 @@ func CreateDestination(didDoc *diddoc.Doc) (*Destination, error) {
}
// if Accept is missing, ensure DIDCommV1 is at least added for packer selection based on MediaTypeProfile.
- if len(didCommService.ServiceEndpoint.Accept) == 0 {
- didCommService.ServiceEndpoint.Accept = []string{defaultDIDCommProfile}
+ if len(didCommService.Accept) == 0 {
+ didCommService.Accept = []string{defaultDIDCommProfile}
}
+
+ sp = model.NewDIDCommV1Endpoint(uri)
}
return &Destination{
- RecipientKeys: didCommService.RecipientKeys,
- ServiceEndpoint: model.Endpoint{
- URI: didCommService.ServiceEndpoint.URI,
- RoutingKeys: didCommService.ServiceEndpoint.RoutingKeys,
- Accept: didCommService.ServiceEndpoint.Accept,
- },
- DIDDoc: didDoc,
+ RecipientKeys: didCommService.RecipientKeys,
+ ServiceEndpoint: sp,
+ RoutingKeys: didCommService.RoutingKeys,
+ MediaTypeProfiles: didCommService.Accept,
+ DIDDoc: didDoc,
}, nil
}
diff --git a/pkg/didcomm/common/service/destination_interop.go b/pkg/didcomm/common/service/destination_interop.go
index 8cebfbfd2..0039ce3ab 100644
--- a/pkg/didcomm/common/service/destination_interop.go
+++ b/pkg/didcomm/common/service/destination_interop.go
@@ -1,3 +1,4 @@
+//go:build ACAPyInterop
// +build ACAPyInterop
/*
@@ -35,7 +36,7 @@ func CreateDestination(didDoc *diddoc.Doc) (*Destination, error) {
}
}
- if didCommService.ServiceEndpoint == "" {
+ if uri, err := didCommService.ServiceEndpoint.URI(); uri == "" || err != nil {
return nil, fmt.Errorf("create destination: no service endpoint on didcomm service block in diddoc: %+v", didDoc)
}
diff --git a/pkg/didcomm/common/service/destination_test.go b/pkg/didcomm/common/service/destination_test.go
index bd34db391..64220688d 100644
--- a/pkg/didcomm/common/service/destination_test.go
+++ b/pkg/didcomm/common/service/destination_test.go
@@ -86,7 +86,7 @@ func TestGetDestinationFromDID(t *testing.T) {
t.Run("fails if the service endpoint is missing", func(t *testing.T) {
diddoc := createDIDDoc()
for i := range diddoc.Service {
- diddoc.Service[i].ServiceEndpoint.URI = ""
+ diddoc.Service[i].ServiceEndpoint = model.NewDIDCommV1Endpoint("")
}
vdr := &mockvdr.MockVDRegistry{ResolveValue: diddoc}
_, err := GetDestination(diddoc.ID, vdr)
@@ -114,16 +114,18 @@ func TestGetDestinationFromDID(t *testing.T) {
func TestPrepareDestination(t *testing.T) {
t.Run("successfully prepared destination", func(t *testing.T) {
- doc := mockdiddoc.GetMockDIDDoc(t)
+ doc := mockdiddoc.GetMockDIDDoc(t, false)
dest, err := CreateDestination(doc)
require.NoError(t, err)
require.NotNil(t, dest)
- require.Equal(t, dest.ServiceEndpoint.URI, "https://localhost:8090")
- require.EqualValues(t, doc.Service[0].ServiceEndpoint.RoutingKeys, dest.ServiceEndpoint.RoutingKeys)
+ uri, err := dest.ServiceEndpoint.URI()
+ require.NoError(t, err)
+ require.Equal(t, uri, "https://localhost:8090")
+ require.EqualValues(t, doc.Service[0].RoutingKeys, dest.RoutingKeys)
})
t.Run("error with destination having recipientKeys not did:keys", func(t *testing.T) {
- doc := mockdiddoc.GetMockDIDDoc(t)
+ doc := mockdiddoc.GetMockDIDDoc(t, false)
doc.Service[0].RecipientKeys = []string{"badKey"}
dest, err := CreateDestination(doc)
@@ -132,7 +134,7 @@ func TestPrepareDestination(t *testing.T) {
})
t.Run("error while getting service", func(t *testing.T) {
- didDoc := mockdiddoc.GetMockDIDDoc(t)
+ didDoc := mockdiddoc.GetMockDIDDoc(t, false)
didDoc.Service = nil
dest, err := CreateDestination(didDoc)
@@ -142,7 +144,7 @@ func TestPrepareDestination(t *testing.T) {
})
t.Run("error while getting recipient keys from did doc", func(t *testing.T) {
- didDoc := mockdiddoc.GetMockDIDDoc(t)
+ didDoc := mockdiddoc.GetMockDIDDoc(t, false)
didDoc.Service[0].RecipientKeys = []string{}
recipientKeys, ok := did.LookupDIDCommRecipientKeys(didDoc)
@@ -183,15 +185,11 @@ func createDIDDocWithKey(pub string) *did.Doc {
}
services := []did.Service{
{
- ID: fmt.Sprintf(didServiceID, id, 1),
- Type: "did-communication",
- ServiceEndpoint: model.Endpoint{
- URI: "http://localhost:58416",
- Accept: nil,
- RoutingKeys: nil,
- },
- Priority: 0,
- RecipientKeys: []string{pubKeyID},
+ ID: fmt.Sprintf(didServiceID, id, 1),
+ Type: "did-communication",
+ ServiceEndpoint: model.NewDIDCommV1Endpoint("http://localhost:58416"),
+ Priority: 0,
+ RecipientKeys: []string{pubKeyID},
},
}
createdTime := time.Now()
diff --git a/pkg/didcomm/dispatcher/outbound/outbound.go b/pkg/didcomm/dispatcher/outbound/outbound.go
index 06051a923..8240957db 100644
--- a/pkg/didcomm/dispatcher/outbound/outbound.go
+++ b/pkg/didcomm/dispatcher/outbound/outbound.go
@@ -107,9 +107,11 @@ func (o *Dispatcher) SendToDID(msg interface{}, myDID, theirDID string) error {
didcommMsg, isMsgMap := msg.(service.DIDCommMsgMap)
+ var isV2 bool
+
if isMsgMap {
- isV2, e := service.IsDIDCommV2(&didcommMsg)
- if e == nil && isV2 {
+ isV2, err = service.IsDIDCommV2(&didcommMsg)
+ if err == nil && isV2 {
connectionVersion = service.V2
} else {
connectionVersion = service.V1
@@ -158,9 +160,9 @@ func (o *Dispatcher) SendToDID(msg interface{}, myDID, theirDID string) error {
"outboundDispatcher.SendToDID failed to get didcomm destination for theirDID [%s]: %w", theirDID, err)
}
- if len(connRec.ServiceEndPoint.Accept) > 0 {
- dest.ServiceEndpoint.Accept = make([]string, len(connRec.ServiceEndPoint.Accept))
- copy(dest.ServiceEndpoint.Accept, connRec.ServiceEndPoint.Accept)
+ if len(connRec.MediaTypeProfiles) > 0 {
+ dest.MediaTypeProfiles = make([]string, len(connRec.MediaTypeProfiles))
+ copy(dest.MediaTypeProfiles, connRec.MediaTypeProfiles)
}
mtp := o.mediaTypeProfile(dest)
@@ -207,13 +209,19 @@ func (o *Dispatcher) getOrCreateConnection(myDID, theirDID string, connectionVer
logger.Debugf("no connection record found for myDID=%s theirDID=%s, will create", myDID, theirDID)
newRecord := connection.Record{
- ConnectionID: uuid.New().String(),
- MyDID: myDID,
- TheirDID: theirDID,
- State: connection.StateNameCompleted,
- Namespace: connection.MyNSPrefix,
- ServiceEndPoint: commonmodel.Endpoint{Accept: o.defaultMediaTypeProfiles()},
- DIDCommVersion: connectionVersion,
+ ConnectionID: uuid.New().String(),
+ MyDID: myDID,
+ TheirDID: theirDID,
+ State: connection.StateNameCompleted,
+ Namespace: connection.MyNSPrefix,
+ DIDCommVersion: connectionVersion,
+ }
+
+ if connectionVersion == service.V2 {
+ newRecord.ServiceEndPoint = commonmodel.NewDIDCommV2Endpoint(
+ []commonmodel.DIDCommV2Endpoint{{Accept: o.defaultMediaTypeProfiles()}})
+ } else {
+ newRecord.MediaTypeProfiles = o.defaultMediaTypeProfiles()
}
err = o.connections.SaveConnectionRecord(&newRecord)
@@ -228,14 +236,21 @@ func (o *Dispatcher) getOrCreateConnection(myDID, theirDID string, connectionVer
func (o *Dispatcher) Send(msg interface{}, senderKey string, des *service.Destination) error { // nolint:funlen,gocyclo
// check if outbound accepts routing keys, else use recipient keys
keys := des.RecipientKeys
- if len(des.ServiceEndpoint.RoutingKeys) != 0 {
- keys = des.ServiceEndpoint.RoutingKeys
+ if routingKeys, err := des.ServiceEndpoint.RoutingKeys(); err == nil && len(routingKeys) > 0 { // DIDComm V2
+ keys = routingKeys
+ } else if len(des.RoutingKeys) > 0 { // DIDComm V1
+ keys = routingKeys
}
var outboundTransport transport.OutboundTransport
for _, v := range o.outboundTransports {
- if v.AcceptRecipient(keys) || v.Accept(des.ServiceEndpoint.URI) {
+ uri, err := des.ServiceEndpoint.URI()
+ if err != nil {
+ logger.Debugf("destination ServiceEndpoint empty: %w, it will not be checked", err)
+ }
+
+ if v.AcceptRecipient(keys) || v.Accept(uri) {
outboundTransport = v
break
}
@@ -292,9 +307,19 @@ func (o *Dispatcher) Send(msg interface{}, senderKey string, des *service.Destin
// Forward forwards the message without packing to the destination.
func (o *Dispatcher) Forward(msg interface{}, des *service.Destination) error {
+ var (
+ uri string
+ err error
+ )
+
+ uri, err = des.ServiceEndpoint.URI()
+ if err != nil {
+ logger.Debugf("destination serviceEndpoint forward URI is not set: %w, will skip value", err)
+ }
+
for _, v := range o.outboundTransports {
if !v.AcceptRecipient(des.RecipientKeys) {
- if !v.Accept(des.ServiceEndpoint.URI) {
+ if !v.Accept(uri) {
continue
}
}
@@ -312,9 +337,10 @@ func (o *Dispatcher) Forward(msg interface{}, des *service.Destination) error {
return nil
}
- return fmt.Errorf("outboundDispatcher.Forward: no transport found for serviceEndpoint: %s", des.ServiceEndpoint.URI)
+ return fmt.Errorf("outboundDispatcher.Forward: no transport found for serviceEndpoint: %s", uri)
}
+//nolint:funlen
func (o *Dispatcher) createForwardMessage(msg []byte, des *service.Destination) ([]byte, error) {
forwardMsgType := service.ForwardMsgType
@@ -342,8 +368,18 @@ func (o *Dispatcher) createForwardMessage(msg []byte, des *service.Destination)
senderKey = []byte(senderDIDKey)
}
- if len(des.ServiceEndpoint.RoutingKeys) == 0 {
- return msg, nil
+ routingKeys, err := des.ServiceEndpoint.RoutingKeys()
+ if err != nil {
+ logger.Debugf("des.ServiceEndpoint.RoutingKeys() (didcomm v2) returned an error %w, "+
+ "will check routinKeys (didcomm v1) array", err)
+ }
+
+ if len(routingKeys) == 0 {
+ if len(des.RoutingKeys) == 0 {
+ return msg, nil
+ }
+
+ routingKeys = des.RoutingKeys
}
// create forward message
@@ -364,7 +400,7 @@ func (o *Dispatcher) createForwardMessage(msg []byte, des *service.Destination)
MediaTypeProfile: mtProfile,
Message: req,
FromKey: senderKey,
- ToKeys: des.ServiceEndpoint.RoutingKeys,
+ ToKeys: routingKeys,
})
if err != nil {
return nil, fmt.Errorf("failed to pack forward msg: %w", err)
@@ -374,8 +410,8 @@ func (o *Dispatcher) createForwardMessage(msg []byte, des *service.Destination)
}
func (o *Dispatcher) addTransportRouteOptions(req []byte, des *service.Destination) ([]byte, error) {
- // dont add transport route options for forward messages
- if len(des.ServiceEndpoint.RoutingKeys) != 0 {
+ // don't add transport route options for forward messages
+ if routingKeys, err := des.ServiceEndpoint.RoutingKeys(); err == nil && len(routingKeys) > 0 {
return req, nil
}
@@ -401,10 +437,18 @@ func (o *Dispatcher) addTransportRouteOptions(req []byte, des *service.Destinati
}
func (o *Dispatcher) mediaTypeProfile(des *service.Destination) string {
- mt := ""
+ var (
+ mt string
+ accept []string
+ err error
+ )
+
+ if accept, err = des.ServiceEndpoint.Accept(); err != nil || len(accept) == 0 { // didcomm v2
+ accept = des.MediaTypeProfiles // didcomm v1
+ }
- if len(des.ServiceEndpoint.Accept) > 0 {
- for _, mtp := range des.ServiceEndpoint.Accept {
+ if len(accept) > 0 {
+ for _, mtp := range accept {
switch mtp {
case transport.MediaTypeV1PlaintextPayload, transport.MediaTypeRFC0019EncryptedEnvelope,
transport.MediaTypeAIP2RFC0019Profile, transport.MediaTypeProfileDIDCommAIP1:
diff --git a/pkg/didcomm/dispatcher/outbound/outbound_test.go b/pkg/didcomm/dispatcher/outbound/outbound_test.go
index d8a45ebc0..545da6d96 100644
--- a/pkg/didcomm/dispatcher/outbound/outbound_test.go
+++ b/pkg/didcomm/dispatcher/outbound/outbound_test.go
@@ -58,7 +58,7 @@ func TestOutboundDispatcher_Send(t *testing.T) {
})
require.NoError(t, err)
require.NoError(t, o.Send("data", mockdiddoc.MockDIDKey(t), &service.Destination{
- ServiceEndpoint: model.Endpoint{URI: "url"},
+ ServiceEndpoint: model.NewDIDCommV1Endpoint("url"),
}))
})
@@ -77,10 +77,10 @@ func TestOutboundDispatcher_Send(t *testing.T) {
require.NoError(t, o.Send("data", fromDIDDoc.KeyAgreement[0].VerificationMethod.ID, &service.Destination{
RecipientKeys: []string{toDIDDoc.KeyAgreement[0].VerificationMethod.ID},
- ServiceEndpoint: model.Endpoint{
+ ServiceEndpoint: model.NewDIDCommV2Endpoint([]model.DIDCommV2Endpoint{{
URI: "url",
Accept: []string{transport.MediaTypeDIDCommV2Profile},
- },
+ }}),
}))
})
@@ -94,7 +94,7 @@ func TestOutboundDispatcher_Send(t *testing.T) {
})
require.NoError(t, err)
err = o.Send("data", mockdiddoc.MockDIDKey(t), &service.Destination{
- ServiceEndpoint: model.Endpoint{URI: "url"},
+ ServiceEndpoint: model.NewDIDCommV1Endpoint("url"),
})
require.Error(t, err)
require.Contains(t, err.Error(), "outboundDispatcher.Send: no transport found for destination")
@@ -110,7 +110,7 @@ func TestOutboundDispatcher_Send(t *testing.T) {
})
require.NoError(t, err)
err = o.Send("data", mockdiddoc.MockDIDKey(t), &service.Destination{
- ServiceEndpoint: model.Endpoint{URI: "url"},
+ ServiceEndpoint: model.NewDIDCommV1Endpoint("url"),
})
require.Error(t, err)
require.Contains(t, err.Error(), "pack error")
@@ -128,7 +128,7 @@ func TestOutboundDispatcher_Send(t *testing.T) {
})
require.NoError(t, err)
err = o.Send("data", mockdiddoc.MockDIDKey(t),
- &service.Destination{ServiceEndpoint: model.Endpoint{URI: "url"}})
+ &service.Destination{ServiceEndpoint: model.NewDIDCommV1Endpoint("url")})
require.Error(t, err)
require.Contains(t, err.Error(), "send error")
})
@@ -144,10 +144,9 @@ func TestOutboundDispatcher_Send(t *testing.T) {
require.NoError(t, err)
require.NoError(t, o.Send("data", mockdiddoc.MockDIDKey(t), &service.Destination{
- ServiceEndpoint: model.Endpoint{
- URI: "url",
- RoutingKeys: []string{"xyz"},
- },
+ ServiceEndpoint: model.NewDIDCommV2Endpoint([]model.DIDCommV2Endpoint{
+ {URI: "url", RoutingKeys: []string{"xyz"}},
+ }),
RecipientKeys: []string{"abc"},
}))
})
@@ -167,10 +166,9 @@ func TestOutboundDispatcher_Send(t *testing.T) {
require.NoError(t, err)
require.NoError(t, o.Send("data", mockdiddoc.MockDIDKey(t), &service.Destination{
- ServiceEndpoint: model.Endpoint{
- URI: "url",
- RoutingKeys: []string{"xyz"},
- },
+ ServiceEndpoint: model.NewDIDCommV2Endpoint([]model.DIDCommV2Endpoint{
+ {URI: "url", RoutingKeys: []string{"xyz"}},
+ }),
RecipientKeys: []string{"abc"},
}))
})
@@ -189,10 +187,9 @@ func TestOutboundDispatcher_Send(t *testing.T) {
require.NoError(t, err)
err = o.Send("data", mockdiddoc.MockDIDKey(t), &service.Destination{
- ServiceEndpoint: model.Endpoint{
- URI: "url",
- RoutingKeys: []string{"xyz"},
- },
+ ServiceEndpoint: model.NewDIDCommV2Endpoint([]model.DIDCommV2Endpoint{
+ {URI: "url", RoutingKeys: []string{"xyz"}},
+ }),
RecipientKeys: []string{"abc"},
})
require.EqualError(t, err, "outboundDispatcher.Send: failed to create forward msg: failed Create "+
@@ -210,10 +207,9 @@ func TestOutboundDispatcher_Send(t *testing.T) {
require.NoError(t, err)
_, err = o.createForwardMessage(createPackedMsgForForward(t), &service.Destination{
- ServiceEndpoint: model.Endpoint{
- URI: "url",
- RoutingKeys: []string{"xyz"},
- },
+ ServiceEndpoint: model.NewDIDCommV2Endpoint([]model.DIDCommV2Endpoint{
+ {URI: "url", RoutingKeys: []string{"xyz"}},
+ }),
RecipientKeys: []string{"abc"},
})
require.Error(t, err)
@@ -228,7 +224,7 @@ type mockMessage struct {
}
func TestOutboundDispatcher_SendToDID(t *testing.T) {
- mockDoc := mockdiddoc.GetMockDIDDoc(t)
+ mockDoc := mockdiddoc.GetMockDIDDoc(t, false)
t.Run("success with existing connection record", func(t *testing.T) {
o, err := NewOutbound(&mockProvider{
@@ -555,7 +551,7 @@ func TestOutboundDispatcherTransportReturnRoute(t *testing.T) {
require.NoError(t, err)
require.NoError(t, o.Send(req, mockdiddoc.MockDIDKey(t),
- &service.Destination{ServiceEndpoint: model.Endpoint{URI: "url"}}))
+ &service.Destination{ServiceEndpoint: model.NewDIDCommV2Endpoint([]model.DIDCommV2Endpoint{{URI: "url"}})}))
})
t.Run("transport route option - value set thread", func(t *testing.T) {
@@ -590,7 +586,7 @@ func TestOutboundDispatcherTransportReturnRoute(t *testing.T) {
require.NoError(t, err)
require.NoError(t, o.Send(req, mockdiddoc.MockDIDKey(t),
- &service.Destination{ServiceEndpoint: model.Endpoint{URI: "url"}}))
+ &service.Destination{ServiceEndpoint: model.NewDIDCommV2Endpoint([]model.DIDCommV2Endpoint{{URI: "url"}})}))
})
t.Run("transport route option - no value set", func(t *testing.T) {
@@ -617,7 +613,7 @@ func TestOutboundDispatcherTransportReturnRoute(t *testing.T) {
require.NoError(t, err)
require.NoError(t, o.Send(req, mockdiddoc.MockDIDKey(t),
- &service.Destination{ServiceEndpoint: model.Endpoint{URI: "url"}}))
+ &service.Destination{ServiceEndpoint: model.NewDIDCommV2Endpoint([]model.DIDCommV2Endpoint{{URI: "url"}})}))
})
t.Run("transport route option - forward message", func(t *testing.T) {
@@ -634,7 +630,9 @@ func TestOutboundDispatcherTransportReturnRoute(t *testing.T) {
testData := []byte("testData")
data, err := o.addTransportRouteOptions(testData,
- &service.Destination{ServiceEndpoint: model.Endpoint{RoutingKeys: []string{"abc"}}})
+ &service.Destination{ServiceEndpoint: model.NewDIDCommV2Endpoint([]model.DIDCommV2Endpoint{
+ {RoutingKeys: []string{"abc"}},
+ })})
require.NoError(t, err)
require.Equal(t, testData, data)
})
@@ -643,14 +641,18 @@ func TestOutboundDispatcherTransportReturnRoute(t *testing.T) {
func TestOutboundDispatcher_Forward(t *testing.T) {
t.Run("test forward - success", func(t *testing.T) {
o, err := NewOutbound(&mockProvider{
- packagerValue: &mockpackager.Packager{},
- outboundTransportsValue: []transport.OutboundTransport{&mockdidcomm.MockOutboundTransport{AcceptValue: true}},
- storageProvider: mockstore.NewMockStoreProvider(),
- protoStorageProvider: mockstore.NewMockStoreProvider(),
- mediaTypeProfiles: []string{transport.MediaTypeDIDCommV2Profile},
+ packagerValue: &mockpackager.Packager{},
+ outboundTransportsValue: []transport.OutboundTransport{&mockdidcomm.MockOutboundTransport{
+ AcceptValue: true,
+ }},
+ storageProvider: mockstore.NewMockStoreProvider(),
+ protoStorageProvider: mockstore.NewMockStoreProvider(),
+ mediaTypeProfiles: []string{transport.MediaTypeDIDCommV2Profile},
})
require.NoError(t, err)
- require.NoError(t, o.Forward("data", &service.Destination{ServiceEndpoint: model.Endpoint{URI: "url"}}))
+ require.NoError(t, o.Forward("data", &service.Destination{
+ ServiceEndpoint: model.NewDIDCommV2Endpoint([]model.DIDCommV2Endpoint{{URI: "url"}}),
+ }))
})
t.Run("test forward - no outbound transport found", func(t *testing.T) {
@@ -662,7 +664,9 @@ func TestOutboundDispatcher_Forward(t *testing.T) {
mediaTypeProfiles: []string{transport.MediaTypeDIDCommV2Profile},
})
require.NoError(t, err)
- err = o.Forward("data", &service.Destination{ServiceEndpoint: model.Endpoint{URI: "url"}})
+ err = o.Forward("data", &service.Destination{
+ ServiceEndpoint: model.NewDIDCommV2Endpoint([]model.DIDCommV2Endpoint{{URI: "url"}}),
+ })
require.Error(t, err)
require.Contains(t, err.Error(), "outboundDispatcher.Forward: no transport found for serviceEndpoint: url")
})
@@ -678,7 +682,8 @@ func TestOutboundDispatcher_Forward(t *testing.T) {
mediaTypeProfiles: []string{transport.MediaTypeDIDCommV2Profile},
})
require.NoError(t, err)
- err = o.Forward("data", &service.Destination{ServiceEndpoint: model.Endpoint{URI: "url"}})
+ err = o.Forward("data", &service.Destination{ServiceEndpoint: model.NewDIDCommV2Endpoint([]model.
+ DIDCommV2Endpoint{{URI: "url"}})})
require.Error(t, err)
require.Contains(t, err.Error(), "send error")
})
diff --git a/pkg/didcomm/packer/legacy/authcrypt/authcrypt_test.go b/pkg/didcomm/packer/legacy/authcrypt/authcrypt_test.go
index b84245bfa..41a5cdf03 100644
--- a/pkg/didcomm/packer/legacy/authcrypt/authcrypt_test.go
+++ b/pkg/didcomm/packer/legacy/authcrypt/authcrypt_test.go
@@ -679,7 +679,8 @@ func Test_getCEK(t *testing.T) {
}
_, err := getCEK(recs, &k)
- require.EqualError(t, err, "getCEK: no key accessible none of the recipient keys were found in kms")
+ require.EqualError(t, err, "getCEK: no key accessible none of the recipient keys were found in kms: "+
+ "[mock error]")
}
func Test_newCryptoBox(t *testing.T) {
diff --git a/pkg/didcomm/packer/legacy/authcrypt/unpack.go b/pkg/didcomm/packer/legacy/authcrypt/unpack.go
index 241982ac9..d1a17ed8a 100644
--- a/pkg/didcomm/packer/legacy/authcrypt/unpack.go
+++ b/pkg/didcomm/packer/legacy/authcrypt/unpack.go
@@ -9,7 +9,6 @@ package authcrypt
import (
"encoding/base64"
"encoding/json"
- "errors"
"fmt"
"github.com/btcsuite/btcutil/base58"
@@ -126,6 +125,8 @@ func getCEK(recipients []recipient, km kms.KeyManager) (*keys, error) {
}
func findVerKey(km kms.KeyManager, candidateKeys []string) (int, error) {
+ var errs []error
+
for i, key := range candidateKeys {
recKID, err := localkms.CreateKID(base58.Decode(key), kms.ED25519Type)
if err != nil {
@@ -136,9 +137,11 @@ func findVerKey(km kms.KeyManager, candidateKeys []string) (int, error) {
if err == nil {
return i, nil
}
+
+ errs = append(errs, err)
}
- return -1, errors.New("none of the recipient keys were found in kms")
+ return -1, fmt.Errorf("none of the recipient keys were found in kms: %v", errs)
}
func decodeSender(b64Sender string, pk []byte, km kms.KeyManager) ([]byte, []byte, error) {
diff --git a/pkg/didcomm/protocol/didexchange/service.go b/pkg/didcomm/protocol/didexchange/service.go
index d8b924b87..bb4f69c82 100644
--- a/pkg/didcomm/protocol/didexchange/service.go
+++ b/pkg/didcomm/protocol/didexchange/service.go
@@ -697,7 +697,11 @@ func (s *Service) CreateConnection(record *connection.Record, theirDID *did.Doc)
return fmt.Errorf("failed to save myDID to the did.ConnectionStore: %w", err)
}
- record.DIDCommVersion = service.V1
+ if isDIDCommV2(record.MediaTypeProfiles) {
+ record.DIDCommVersion = service.V2
+ } else {
+ record.DIDCommVersion = service.V1
+ }
return s.connectionRecorder.SaveConnectionRecord(record)
}
@@ -719,6 +723,7 @@ func (s *Service) connectionRecord(msg service.DIDCommMsg) (*connection.Record,
return nil, errors.New("invalid message type")
}
+//nolint:funlen
func (s *Service) oobInvitationMsgRecord(msg service.DIDCommMsg) (*connection.Record, error) {
thID, err := msg.ThreadID()
if err != nil {
@@ -737,20 +742,40 @@ func (s *Service) oobInvitationMsgRecord(msg service.DIDCommMsg) (*connection.Re
return nil, fmt.Errorf("failed to get the did service block from oob invitation : %w", err)
}
- connRecord := &connection.Record{
- ConnectionID: generateRandomID(),
- ThreadID: thID,
- ParentThreadID: oobInvitation.ThreadID,
- State: stateNameNull,
- InvitationID: oobInvitation.ID,
- ServiceEndPoint: model.Endpoint{
- URI: svc.ServiceEndpoint.URI, // TODO: service endpoint should be 'theirs' not 'mine'.
- Accept: svc.ServiceEndpoint.Accept,
- },
- RecipientKeys: svc.RecipientKeys, // TODO: recipient keys should be 'theirs' not 'mine'.
- TheirLabel: oobInvitation.TheirLabel,
- Namespace: findNamespace(msg.Type()),
- DIDCommVersion: service.V1,
+ uri, err := svc.ServiceEndpoint.URI()
+ if err != nil {
+ logger.Debugf("service DIDComm V1 without ServiceEndpoint URI: %w, skipping it", err)
+ }
+
+ var connRecord *connection.Record
+
+ if accept, err := svc.ServiceEndpoint.Accept(); err == nil && isDIDCommV2(accept) {
+ connRecord = &connection.Record{
+ ConnectionID: generateRandomID(),
+ ThreadID: thID,
+ ParentThreadID: oobInvitation.ThreadID,
+ State: stateNameNull,
+ InvitationID: oobInvitation.ID,
+ ServiceEndPoint: svc.ServiceEndpoint,
+ RecipientKeys: svc.RecipientKeys, // TODO: recipient keys should be 'theirs' not 'mine'.
+ TheirLabel: oobInvitation.TheirLabel,
+ Namespace: findNamespace(msg.Type()),
+ DIDCommVersion: service.V2,
+ }
+ } else {
+ connRecord = &connection.Record{
+ ConnectionID: generateRandomID(),
+ ThreadID: thID,
+ ParentThreadID: oobInvitation.ThreadID,
+ State: stateNameNull,
+ InvitationID: oobInvitation.ID,
+ ServiceEndPoint: model.NewDIDCommV1Endpoint(uri),
+ RecipientKeys: svc.RecipientKeys, // TODO: recipient keys should be 'theirs' not 'mine'.
+ TheirLabel: oobInvitation.TheirLabel,
+ Namespace: findNamespace(msg.Type()),
+ MediaTypeProfiles: svc.Accept,
+ DIDCommVersion: service.V1,
+ }
}
publicDID, ok := oobInvitation.Target.(string)
@@ -785,20 +810,16 @@ func (s *Service) invitationMsgRecord(msg service.DIDCommMsg) (*connection.Recor
}
connRecord := &connection.Record{
- ConnectionID: generateRandomID(),
- ThreadID: thID,
- State: stateNameNull,
- InvitationID: invitation.ID,
- InvitationDID: invitation.DID,
- ServiceEndPoint: model.Endpoint{
- URI: invitation.ServiceEndpoint,
- Accept: nil,
- RoutingKeys: nil,
- },
- RecipientKeys: []string{recKey},
- TheirLabel: invitation.Label,
- Namespace: findNamespace(msg.Type()),
- DIDCommVersion: service.V1,
+ ConnectionID: generateRandomID(),
+ ThreadID: thID,
+ State: stateNameNull,
+ InvitationID: invitation.ID,
+ InvitationDID: invitation.DID,
+ ServiceEndPoint: model.NewDIDCommV1Endpoint(invitation.ServiceEndpoint),
+ RecipientKeys: []string{recKey},
+ TheirLabel: invitation.Label,
+ Namespace: findNamespace(msg.Type()),
+ DIDCommVersion: service.V1,
}
if err := s.connectionRecorder.SaveConnectionRecord(connRecord); err != nil {
@@ -918,6 +939,7 @@ type options struct {
// CreateImplicitInvitation creates implicit invitation. Inviter DID is required, invitee DID is optional.
// If invitee DID is not provided new peer DID will be created for implicit invitation exchange request.
+//nolint:funlen
func (s *Service) CreateImplicitInvitation(inviterLabel, inviterDID,
inviteeLabel, inviteeDID string, routerConnections []string) (string, error) {
logger.Debugf("implicit invitation requested inviterDID[%s] inviteeDID[%s]", inviterDID, inviteeDID)
@@ -933,16 +955,35 @@ func (s *Service) CreateImplicitInvitation(inviterLabel, inviterDID,
}
thID := generateRandomID()
- connRecord := &connection.Record{
- ConnectionID: generateRandomID(),
- ThreadID: thID,
- State: stateNameNull,
- InvitationDID: inviterDID,
- Implicit: true,
- ServiceEndPoint: dest.ServiceEndpoint,
- RecipientKeys: dest.RecipientKeys,
- TheirLabel: inviterLabel,
- Namespace: findNamespace(InvitationMsgType),
+
+ var connRecord *connection.Record
+
+ if accept, e := dest.ServiceEndpoint.Accept(); e == nil && isDIDCommV2(accept) {
+ connRecord = &connection.Record{
+ ConnectionID: generateRandomID(),
+ ThreadID: thID,
+ State: stateNameNull,
+ InvitationDID: inviterDID,
+ Implicit: true,
+ ServiceEndPoint: dest.ServiceEndpoint,
+ RecipientKeys: dest.RecipientKeys,
+ TheirLabel: inviterLabel,
+ Namespace: findNamespace(InvitationMsgType),
+ }
+ } else {
+ connRecord = &connection.Record{
+ ConnectionID: generateRandomID(),
+ ThreadID: thID,
+ State: stateNameNull,
+ InvitationDID: inviterDID,
+ Implicit: true,
+ ServiceEndPoint: dest.ServiceEndpoint,
+ RecipientKeys: dest.RecipientKeys,
+ RoutingKeys: dest.RoutingKeys,
+ MediaTypeProfiles: dest.MediaTypeProfiles,
+ TheirLabel: inviterLabel,
+ Namespace: findNamespace(InvitationMsgType),
+ }
}
if e := s.connectionRecorder.SaveConnectionRecordWithMappings(connRecord); e != nil {
diff --git a/pkg/didcomm/protocol/didexchange/service_test.go b/pkg/didcomm/protocol/didexchange/service_test.go
index d0ed8ae4c..6a885ce8b 100644
--- a/pkg/didcomm/protocol/didexchange/service_test.go
+++ b/pkg/didcomm/protocol/didexchange/service_test.go
@@ -406,7 +406,9 @@ func TestService_Handle_Invitee(t *testing.T) {
require.Equal(t, (&requested{}).Name(), connRecord.State)
require.Equal(t, invitation.ID, connRecord.InvitationID)
require.Equal(t, invitation.RecipientKeys, connRecord.RecipientKeys)
- require.Equal(t, invitation.ServiceEndpoint, connRecord.ServiceEndPoint.URI)
+ uri, err := connRecord.ServiceEndPoint.URI()
+ require.NoError(t, err)
+ require.Equal(t, invitation.ServiceEndpoint, uri)
didKey, err := ctx.getVerKey(invitation.ID)
require.NoError(t, err)
@@ -694,7 +696,7 @@ func TestCreateConnection(t *testing.T) {
TheirLabel: uuid.New().String(),
TheirDID: theirDID.ID,
MyDID: newPeerDID(t, k).ID,
- ServiceEndPoint: commonmodel.Endpoint{URI: "http://example.com"},
+ ServiceEndPoint: commonmodel.NewDIDCommV1Endpoint("http://example.com"),
RecipientKeys: []string{"testkeys"},
InvitationID: uuid.New().String(),
Namespace: myNSPrefix,
@@ -954,7 +956,7 @@ func TestContinueWithPublicDID(t *testing.T) {
keyType: kms.ED25519Type,
keyAgreementType: kms.X25519ECDHKWType,
}
- didDoc := mockdiddoc.GetMockDIDDoc(t)
+ didDoc := mockdiddoc.GetMockDIDDoc(t, false)
svc, err := New(&protocol.MockProvider{
ServiceMap: map[string]interface{}{
mediator.Coordination: &mockroute.MockMediatorSvc{},
@@ -2015,7 +2017,7 @@ func generateRequestMsgPayload(t *testing.T, prov provider, id, invitationID str
ctx := context{
outboundDispatcher: prov.OutboundDispatcher(),
- vdRegistry: &mockvdr.MockVDRegistry{CreateValue: mockdiddoc.GetMockDIDDoc(t)},
+ vdRegistry: &mockvdr.MockVDRegistry{CreateValue: mockdiddoc.GetMockDIDDoc(t, false)},
connectionRecorder: connRec,
}
doc, err := ctx.vdRegistry.Create(testMethod, nil)
@@ -2183,7 +2185,7 @@ func TestRespondTo(t *testing.T) {
ID: uuid.New().String(),
Type: "did-communication",
RecipientKeys: []string{"did:key:1234567"},
- ServiceEndpoint: commonmodel.Endpoint{URI: "http://example.com"},
+ ServiceEndpoint: commonmodel.NewDIDCommV1Endpoint("http://example.com"),
}), nil)
require.NoError(t, err)
require.NotEmpty(t, connID)
@@ -2248,7 +2250,7 @@ func TestRespondTo(t *testing.T) {
func TestSave(t *testing.T) {
t.Run("saves invitation", func(t *testing.T) {
- expected := newOOBInvite("did:example:public")
+ expected := newOOBInvite([]string{transport.MediaTypeRFC0019EncryptedEnvelope}, "did:example:public")
provider := testProvider()
provider.StoreProvider = &mockstorage.MockStoreProvider{
Custom: &mockStore{
@@ -2276,7 +2278,7 @@ func TestSave(t *testing.T) {
}
s, err := New(provider)
require.NoError(t, err)
- err = s.SaveInvitation(newOOBInvite("did:example:public"))
+ err = s.SaveInvitation(newOOBInvite([]string{transport.MediaTypeRFC0019EncryptedEnvelope}, "did:example:public"))
require.Error(t, err)
require.True(t, errors.Is(err, expected))
})
@@ -2324,7 +2326,7 @@ func newPeerDID(t *testing.T, k kms.KeyManager) *did.Doc {
Type: "did-communication",
Priority: 0,
RecipientKeys: []string{base58.Encode(pubKey)},
- ServiceEndpoint: commonmodel.Endpoint{URI: "http://example.com"},
+ ServiceEndpoint: commonmodel.NewDIDCommV1Endpoint("http://example.com"),
}}),
)
require.NoError(t, err)
diff --git a/pkg/didcomm/protocol/didexchange/states.go b/pkg/didcomm/protocol/didexchange/states.go
index 9d1920c66..059f297f3 100644
--- a/pkg/didcomm/protocol/didexchange/states.go
+++ b/pkg/didcomm/protocol/didexchange/states.go
@@ -324,8 +324,10 @@ func (ctx *context) handleInboundOOBInvitation(oobInv *OOBInvitation, thid strin
}
dest := &service.Destination{
- RecipientKeys: svc.RecipientKeys,
- ServiceEndpoint: svc.ServiceEndpoint,
+ RecipientKeys: svc.RecipientKeys,
+ ServiceEndpoint: svc.ServiceEndpoint,
+ RoutingKeys: svc.RoutingKeys,
+ MediaTypeProfiles: svc.Accept,
}
connRec.ThreadID = thid
@@ -360,9 +362,14 @@ func (ctx *context) createInvitedRequest(destination *service.Destination, label
},
}
+ accept, err := destination.ServiceEndpoint.Accept() // didcomm v2
+ if err != nil {
+ accept = destination.MediaTypeProfiles // didcomm v1
+ }
+
// get did document to use in exchange request
myDIDDoc, err := ctx.getMyDIDDoc(getPublicDID(options), getRouterConnections(options),
- serviceTypeByMediaProfile(destination.ServiceEndpoint.Accept))
+ serviceTypeByMediaProfile(accept))
if err != nil {
return nil, nil, err
}
@@ -448,7 +455,12 @@ func (ctx *context) handleInboundRequest(request *Request, options *options,
if len(requestDidDoc.Service) > 0 {
serviceType = requestDidDoc.Service[0].Type
} else {
- serviceType = serviceTypeByMediaProfile(destination.ServiceEndpoint.Accept)
+ accept, e := destination.ServiceEndpoint.Accept()
+ if e != nil {
+ accept = []string{}
+ }
+
+ serviceType = serviceTypeByMediaProfile(accept)
}
responseDidDoc, err := ctx.getMyDIDDoc(myDID, getRouterConnections(options), serviceType)
@@ -488,8 +500,13 @@ func (ctx *context) handleInboundRequest(request *Request, options *options,
connRec.TheirDID = request.DID
connRec.TheirLabel = request.Label
- if len(destination.ServiceEndpoint.Accept) > 0 {
- connRec.ServiceEndPoint.Accept = destination.ServiceEndpoint.Accept
+ accept, err := destination.ServiceEndpoint.Accept()
+ if err != nil {
+ accept = []string{}
+ }
+
+ if len(accept) > 0 {
+ connRec.MediaTypeProfiles = accept
}
// send exchange response
@@ -628,14 +645,27 @@ func (ctx *context) getDestination(invitation *Invitation) (*service.Destination
return service.GetDestination(invitation.DID, ctx.vdRegistry)
}
- return &service.Destination{
- RecipientKeys: invitation.RecipientKeys,
- ServiceEndpoint: model.Endpoint{
- URI: invitation.ServiceEndpoint,
- Accept: ctx.mediaTypeProfiles,
- RoutingKeys: invitation.RoutingKeys,
- },
- }, nil
+ accept := ctx.mediaTypeProfiles
+
+ var dest *service.Destination
+
+ if isDIDCommV2(accept) {
+ dest = &service.Destination{
+ RecipientKeys: invitation.RecipientKeys,
+ ServiceEndpoint: model.NewDIDCommV2Endpoint([]model.DIDCommV2Endpoint{
+ {URI: invitation.ServiceEndpoint, Accept: accept, RoutingKeys: invitation.RoutingKeys},
+ }),
+ }
+ } else {
+ dest = &service.Destination{
+ RecipientKeys: invitation.RecipientKeys,
+ ServiceEndpoint: model.NewDIDCommV1Endpoint(invitation.ServiceEndpoint),
+ MediaTypeProfiles: accept,
+ RoutingKeys: invitation.RoutingKeys,
+ }
+ }
+
+ return dest, nil
}
// nolint:gocyclo,funlen
@@ -670,10 +700,23 @@ func (ctx *context) getMyDIDDoc(pubDID string, routerConnections []string, servi
return nil, fmt.Errorf("did doc - fetch router config: %w", err)
}
- services = append(services, did.Service{ServiceEndpoint: model.Endpoint{
- URI: serviceEndpoint,
- RoutingKeys: routingKeys,
- }})
+ var svc did.Service
+
+ if serviceType == didCommServiceType {
+ svc = did.Service{
+ Type: didCommServiceType,
+ ServiceEndpoint: model.NewDIDCommV1Endpoint(serviceEndpoint),
+ RoutingKeys: routingKeys,
+ }
+ } else if serviceType == didCommV2ServiceType {
+ svc = did.Service{
+ ServiceEndpoint: model.NewDIDCommV2Endpoint([]model.DIDCommV2Endpoint{
+ {URI: serviceEndpoint, RoutingKeys: routingKeys},
+ }),
+ }
+ }
+
+ services = append(services, svc)
}
if len(services) == 0 {
@@ -949,6 +992,8 @@ func (ctx *context) getVerKeyFromOOBInvitation(invitationID string) (string, err
return "", errVerKeyNotFound
}
+ unmarshalServiceEndpointInOOBTarget(&invitation)
+
pubKey, err := ctx.resolveVerKey(&invitation)
if err != nil {
return "", fmt.Errorf("failed to get my verkey: %w", err)
@@ -957,6 +1002,40 @@ func (ctx *context) getVerKeyFromOOBInvitation(invitationID string) (string, err
return pubKey, nil
}
+//nolint:nestif
+func unmarshalServiceEndpointInOOBTarget(invitation *OOBInvitation) {
+ // for DIDCommV1, oobInvitation's target serviceEndpoint is a string, transform it to model.Endpoint map equivalent
+ // for a successful service decode().
+ // for DIDCommV2, transform the target from map[string]interface{} to model.Endpoint
+ if targetMap, ok := invitation.Target.(map[string]interface{}); ok {
+ if se, ok := targetMap["serviceEndpoint"]; ok {
+ seStr, ok := se.(string)
+ if ok {
+ targetMap["serviceEndpoint"] = model.NewDIDCommV1Endpoint(seStr)
+ } else if seMap, ok := se.(map[string]interface{}); ok {
+ seStr, ok = seMap["uri"].(string)
+ if !ok {
+ seStr = ""
+ }
+
+ accept, ok := seMap["accept"].([]string)
+ if !ok {
+ accept = []string{}
+ }
+
+ routingKeys, ok := seMap["routingKeys"].([]string)
+ if !ok {
+ routingKeys = []string{}
+ }
+
+ targetMap["serviceEndpoint"] = model.NewDIDCommV2Endpoint([]model.DIDCommV2Endpoint{
+ {URI: seStr, Accept: accept, RoutingKeys: routingKeys},
+ })
+ }
+ }
+ }
+}
+
// nolint:gocyclo,funlen
func (ctx *context) getServiceBlock(i *OOBInvitation) (*did.Service, error) {
logger.Debugf("extracting service block from oobinvitation=%+v", i)
@@ -1006,7 +1085,15 @@ func (ctx *context) getServiceBlock(i *OOBInvitation) (*did.Service, error) {
err = decoder.Decode(svc)
if err != nil {
- return nil, fmt.Errorf("failed to decode service block : %w", err)
+ // TODO this error check depend on mapstructure decoding 'ServiceEndpoint' section of service.
+ // TODO Find a better way to build it.
+ // for DIDCommV2, decoder.Decode(svc) doesn't support serviceEndpoint as []interface{} representing an array
+ // for model.Endpoint. Manually build the endpoint here in this case.
+ if strings.Contains(err.Error(), "'serviceEndpoint' expected a map, got 'slice'") {
+ extractDIDCommV2EndpointIntoService(svc, &s)
+ } else {
+ return nil, fmt.Errorf("failed to decode service block : %w", err)
+ }
}
block = &s
@@ -1014,6 +1101,7 @@ func (ctx *context) getServiceBlock(i *OOBInvitation) (*did.Service, error) {
return nil, fmt.Errorf("unsupported target type: %+v", svc)
}
+ //nolint:nestif
if len(i.MediaTypeProfiles) > 0 {
// marshal/unmarshal to "clone" service block
blockBytes, err := json.Marshal(block)
@@ -1031,7 +1119,23 @@ func (ctx *context) getServiceBlock(i *OOBInvitation) (*did.Service, error) {
// updating Accept header requires a cloned service block to avoid Data Race errors.
// RFC0587: In case the accept property is set in both the DID service block and the out-of-band message,
// the out-of-band property takes precedence.
- block.ServiceEndpoint.Accept = i.MediaTypeProfiles
+ if isDIDCommV2(i.MediaTypeProfiles) {
+ uri, err := block.ServiceEndpoint.URI()
+ if err != nil {
+ logger.Debugf("block ServiceEndpoint URI empty for DIDcomm V2, skipping it.")
+ }
+
+ routingKeys, err := block.ServiceEndpoint.RoutingKeys()
+ if err != nil {
+ logger.Debugf("block ServiceEndpoint RoutingKeys empty for DIDcomm V2, skipping these.")
+ }
+
+ block.ServiceEndpoint = model.NewDIDCommV2Endpoint([]model.DIDCommV2Endpoint{
+ {URI: uri, Accept: i.MediaTypeProfiles, RoutingKeys: routingKeys},
+ })
+ } else {
+ block.Accept = i.MediaTypeProfiles
+ }
}
logger.Debugf("extracted service block=%+v", block)
@@ -1039,6 +1143,58 @@ func (ctx *context) getServiceBlock(i *OOBInvitation) (*did.Service, error) {
return block, nil
}
+//nolint:gocognit,gocyclo,nestif
+func extractDIDCommV2EndpointIntoService(svc map[string]interface{}, s *did.Service) {
+ if svcEndpointModel, ok := svc["serviceEndpoint"]; ok {
+ if svcEndpointArr, ok := svcEndpointModel.([]interface{}); ok && len(svcEndpointArr) > 0 {
+ if svcEndpointMap, ok := svcEndpointArr[0].(map[string]interface{}); ok {
+ var (
+ uri string
+ accept []string
+ routingKeys []string
+ )
+
+ if uriVal, ok := svcEndpointMap["uri"]; ok {
+ if uri, ok = uriVal.(string); !ok {
+ uri = ""
+ }
+ }
+
+ if acceptVal, ok := svcEndpointMap["accept"]; ok {
+ if acceptArr, ok := acceptVal.([]interface{}); ok {
+ for _, a := range acceptArr {
+ accept = append(accept, a.(string))
+ }
+ }
+ }
+
+ if routingKeysVal, ok := svcEndpointMap["routingKeys"]; ok {
+ if routingKeysArr, ok := routingKeysVal.([]interface{}); ok {
+ for _, r := range routingKeysArr {
+ routingKeys = append(routingKeys, r.(string))
+ }
+ }
+ }
+
+ s.ServiceEndpoint = model.NewDIDCommV2Endpoint([]model.DIDCommV2Endpoint{
+ {URI: uri, Accept: accept, RoutingKeys: routingKeys},
+ })
+ }
+ }
+ }
+}
+
+func isDIDCommV2(mediaTypeProfiles []string) bool {
+ for _, mtp := range mediaTypeProfiles {
+ switch mtp {
+ case transport.MediaTypeDIDCommV2Profile, transport.MediaTypeAIP2RFC0587Profile:
+ return true
+ }
+ }
+
+ return false
+}
+
func interopSovService(doc *did.Doc) (*did.Service, error) {
s, found := did.LookupService(doc, "endpoint")
if !found {
diff --git a/pkg/didcomm/protocol/didexchange/states_test.go b/pkg/didcomm/protocol/didexchange/states_test.go
index f70fb697a..3cc5a347d 100644
--- a/pkg/didcomm/protocol/didexchange/states_test.go
+++ b/pkg/didcomm/protocol/didexchange/states_test.go
@@ -400,7 +400,7 @@ func TestRequestedState_Execute(t *testing.T) {
Type: didServiceType,
Priority: 0,
RecipientKeys: []string{"key"},
- ServiceEndpoint: commonmodel.Endpoint{URI: "http://test.com"},
+ ServiceEndpoint: commonmodel.NewDIDCommV1Endpoint("http://test.com"),
},
}),
connRecord: &connection.Record{},
@@ -453,7 +453,7 @@ func TestRequestedState_Execute(t *testing.T) {
Type: didServiceType,
Priority: 0,
RecipientKeys: []string{"key"},
- ServiceEndpoint: commonmodel.Endpoint{URI: "http://test.com"},
+ ServiceEndpoint: commonmodel.NewDIDCommV1Endpoint("http://test.com"),
},
}),
connRecord: &connection.Record{},
@@ -509,7 +509,8 @@ func TestRequestedState_Execute(t *testing.T) {
_, encKey := newSigningAndEncryptionDIDKeys(t, tc.ctx)
- inv := newOOBInvite(newServiceBlock([]string{encKey}, []string{encKey}, didServiceType))
+ inv := newOOBInvite(tc.ctx.mediaTypeProfiles, newServiceBlock([]string{encKey}, []string{encKey},
+ didServiceType))
inv.MyLabel = expected
_, _, action, e := (&requested{}).ExecuteInbound(&stateMachineMsg{
DIDCommMsg: service.NewDIDCommMsgMap(inv),
@@ -561,13 +562,22 @@ func TestRequestedState_Execute(t *testing.T) {
if didServiceType == vdrapi.DIDCommV2ServiceType {
expected = doc.KeyAgreement[0].VerificationMethod.ID
+
+ doc.Service = []diddoc.Service{{
+ Type: didServiceType,
+ ServiceEndpoint: commonmodel.NewDIDCommV2Endpoint([]commonmodel.DIDCommV2Endpoint{
+ {URI: "http://test.com", Accept: []string{"didcomm/v2"}},
+ }),
+ RecipientKeys: []string{expected},
+ }}
+ } else {
+ doc.Service = []diddoc.Service{{
+ Type: didServiceType,
+ ServiceEndpoint: commonmodel.NewDIDCommV1Endpoint("http://test.com"),
+ RecipientKeys: []string{expected},
+ }}
}
- doc.Service = []diddoc.Service{{
- Type: didServiceType,
- ServiceEndpoint: commonmodel.Endpoint{URI: "http://test.com"},
- RecipientKeys: []string{expected},
- }}
tc.ctx.vdRegistry = &mockvdr.MockVDRegistry{
CreateValue: doc,
}
@@ -585,6 +595,7 @@ func TestRequestedState_Execute(t *testing.T) {
_, _, _, err = (&requested{}).ExecuteInbound(&stateMachineMsg{
options: &options{routerConnections: []string{"xyz"}},
DIDCommMsg: service.NewDIDCommMsgMap(newOOBInvite(
+ tc.ctx.mediaTypeProfiles,
newServiceBlock([]string{encKey}, []string{encKey}, didServiceType))),
connRecord: &connection.Record{},
}, "", tc.ctx)
@@ -639,14 +650,16 @@ func TestRequestedState_Execute(t *testing.T) {
options ...vdrapi.DIDMethodOption) (*diddoc.DocResolution, error) {
created = true
- require.Equal(t, expected.Keys(), didDoc.Service[0].ServiceEndpoint.RoutingKeys)
- require.Equal(t, expected.Endpoint(), didDoc.Service[0].ServiceEndpoint.URI)
+ uri, e := didDoc.Service[0].ServiceEndpoint.URI()
+ require.NoError(t, e)
+ require.Equal(t, expected.Endpoint(), uri)
return &diddoc.DocResolution{DIDDocument: docResolution}, nil
},
ResolveValue: docResolution,
}
- oobInvite := newOOBInvite(newServiceBlock([]string{encKey}, []string{encKey}, didServiceType))
+ oobInvite := newOOBInvite(tc.ctx.mediaTypeProfiles, newServiceBlock(
+ []string{encKey}, []string{encKey}, didServiceType))
_, _, _, err = (&requested{}).ExecuteInbound(&stateMachineMsg{
options: &options{routerConnections: []string{"xyz"}},
DIDCommMsg: service.NewDIDCommMsgMap(oobInvite),
@@ -701,14 +714,11 @@ func TestRequestedState_Execute(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
myDoc := createDIDDoc(t, tc.ctx)
myDoc.Service = []diddoc.Service{{
- ID: uuid.New().String(),
- Type: "invalid",
- Priority: 0,
- RecipientKeys: nil,
- ServiceEndpoint: commonmodel.Endpoint{
- URI: "",
- RoutingKeys: nil,
- },
+ ID: uuid.New().String(),
+ Type: "invalid",
+ Priority: 0,
+ RecipientKeys: nil,
+ ServiceEndpoint: commonmodel.NewDIDCommV2Endpoint([]commonmodel.DIDCommV2Endpoint{{}}),
}}
tc.ctx.vdRegistry = &mockvdr.MockVDRegistry{CreateValue: myDoc}
_, _, _, err = (&requested{}).ExecuteInbound(&stateMachineMsg{
@@ -751,14 +761,11 @@ func TestRequestedState_Execute(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
myDoc := createDIDDoc(t, tc.ctx)
myDoc.Service = []diddoc.Service{{
- ID: uuid.New().String(),
- Type: "invalid",
- Priority: 0,
- RecipientKeys: nil,
- ServiceEndpoint: commonmodel.Endpoint{
- URI: "",
- RoutingKeys: nil,
- },
+ ID: uuid.New().String(),
+ Type: "invalid",
+ Priority: 0,
+ RecipientKeys: nil,
+ ServiceEndpoint: commonmodel.NewDIDCommV2Endpoint([]commonmodel.DIDCommV2Endpoint{{}}),
}}
tc.ctx.vdRegistry = &mockvdr.MockVDRegistry{CreateValue: myDoc}
_, _, _, err = (&requested{}).ExecuteInbound(&stateMachineMsg{
@@ -772,7 +779,7 @@ func TestRequestedState_Execute(t *testing.T) {
Type: didServiceType,
Priority: 0,
RecipientKeys: []string{"key"},
- ServiceEndpoint: commonmodel.Endpoint{URI: "http://test.com"},
+ ServiceEndpoint: commonmodel.NewDIDCommV1Endpoint("http://test.com"),
},
}),
connRecord: &connection.Record{},
@@ -827,23 +834,23 @@ func TestRespondedState_Execute(t *testing.T) {
ctx *context
}{
{
- name: "using context with ED25519 main VM and X25519 keyAgreement",
+ name: fmt.Sprintf("using context with ED25519 main VM and X25519 keyAgreement with profile %s", mtp),
ctx: getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, mtp),
},
{
- name: "using context with P-256 main VM and P-256 keyAgreement",
+ name: fmt.Sprintf("using context with P-256 main VM and P-256 keyAgreement with profile %s", mtp),
ctx: getContext(t, &prov, kms.ECDSAP256TypeIEEEP1363, kms.NISTP256ECDHKWType, mtp),
},
{
- name: "using context with P-384 main VM and P-384 keyAgreement",
+ name: fmt.Sprintf("using context with P-384 main VM and P-384 keyAgreement with profile %s", mtp),
ctx: getContext(t, &prov, kms.ECDSAP384TypeIEEEP1363, kms.NISTP384ECDHKWType, mtp),
},
{
- name: "using context with P-521 main VM and P-521 keyAgreement",
+ name: fmt.Sprintf("using context with P-521 main VM and P-521 keyAgreement with profile %s", mtp),
ctx: getContext(t, &prov, kms.ECDSAP521TypeIEEEP1363, kms.NISTP521ECDHKWType, mtp),
},
{
- name: "using context with ED25519 main VM and P-384 keyAgreement",
+ name: fmt.Sprintf("using context with ED25519 main VM and P-384 keyAgreement with profile %s", mtp),
ctx: getContext(t, &prov, kms.ED25519Type, kms.NISTP384ECDHKWType, mtp),
},
}
@@ -914,14 +921,11 @@ func TestRespondedState_Execute(t *testing.T) {
ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, mtp)
myDoc := createDIDDoc(t, ctx)
myDoc.Service = []diddoc.Service{{
- ID: uuid.New().String(),
- Type: "invalid",
- Priority: 0,
- RecipientKeys: nil,
- ServiceEndpoint: commonmodel.Endpoint{
- URI: "",
- RoutingKeys: nil,
- },
+ ID: uuid.New().String(),
+ Type: "invalid",
+ Priority: 0,
+ RecipientKeys: nil,
+ ServiceEndpoint: commonmodel.NewDIDCommV2Endpoint([]commonmodel.DIDCommV2Endpoint{{}}),
}}
ctx.vdRegistry = &mockvdr.MockVDRegistry{CreateValue: myDoc}
_, _, _, err := (&responded{}).ExecuteInbound(&stateMachineMsg{
@@ -999,7 +1003,7 @@ func TestCompletedState_Execute(t *testing.T) {
}
err = ctx.connectionRecorder.SaveConnectionRecordWithMappings(connRec)
require.NoError(t, err)
- ctx.vdRegistry = &mockvdr.MockVDRegistry{ResolveValue: mockdiddoc.GetMockDIDDoc(t)}
+ ctx.vdRegistry = &mockvdr.MockVDRegistry{ResolveValue: mockdiddoc.GetMockDIDDoc(t, false)}
require.NoError(t, err)
_, followup, _, e := (&completed{}).ExecuteInbound(&stateMachineMsg{
DIDCommMsg: bytesToDIDCommMsg(t, responsePayloadBytes),
@@ -1267,11 +1271,11 @@ func TestNewResponseFromRequest(t *testing.T) {
})
t.Run("unsuccessful new response from request due to create did error", func(t *testing.T) {
- didDoc := mockdiddoc.GetMockDIDDoc(t)
+ didDoc := mockdiddoc.GetMockDIDDoc(t, false)
ctx := &context{
vdRegistry: &mockvdr.MockVDRegistry{
CreateErr: fmt.Errorf("create DID error"),
- ResolveValue: mockdiddoc.GetMockDIDDoc(t),
+ ResolveValue: mockdiddoc.GetMockDIDDoc(t, false),
},
routeSvc: &mockroute.MockMediatorSvc{},
}
@@ -1307,7 +1311,7 @@ func TestNewResponseFromRequest(t *testing.T) {
require.NotNil(t, didConnStore)
ctx := &context{
- vdRegistry: &mockvdr.MockVDRegistry{CreateValue: mockdiddoc.GetMockDIDDoc(t)},
+ vdRegistry: &mockvdr.MockVDRegistry{CreateValue: mockdiddoc.GetMockDIDDoc(t, false)},
crypto: &mockcrypto.Crypto{SignErr: errors.New("sign error")},
connectionRecorder: connRec,
connectionStore: didConnStore,
@@ -1362,7 +1366,7 @@ func TestPrepareResponse(t *testing.T) {
request, err := createRequest(t, ctx, false, transport.MediaTypeRFC0019EncryptedEnvelope)
require.NoError(t, err)
- _, err = ctx.prepareResponse(request, mockdiddoc.GetMockDIDDoc(t))
+ _, err = ctx.prepareResponse(request, mockdiddoc.GetMockDIDDoc(t, false))
require.NoError(t, err)
})
@@ -1373,7 +1377,7 @@ func TestPrepareResponse(t *testing.T) {
request, err := createRequest(t, ctx, false, transport.MediaTypeRFC0019EncryptedEnvelope)
require.NoError(t, err)
- _, err = ctx.prepareResponse(request, mockdiddoc.GetMockDIDDoc(t))
+ _, err = ctx.prepareResponse(request, mockdiddoc.GetMockDIDDoc(t, false))
require.NoError(t, err)
})
@@ -1395,7 +1399,7 @@ func TestPrepareResponse(t *testing.T) {
request, err := createRequest(t, ctx, false, transport.MediaTypeRFC0019EncryptedEnvelope)
require.NoError(t, err)
- _, err = ctx.prepareResponse(request, mockdiddoc.GetMockDIDDoc(t))
+ _, err = ctx.prepareResponse(request, mockdiddoc.GetMockDIDDoc(t, false))
require.Error(t, err)
require.True(t, errors.Is(err, expected))
})
@@ -1410,7 +1414,7 @@ func TestPrepareResponse(t *testing.T) {
ctx.kms = &mockkms.KeyManager{GetKeyErr: expected}
- _, err = ctx.prepareResponse(request, mockdiddoc.GetMockDIDDoc(t))
+ _, err = ctx.prepareResponse(request, mockdiddoc.GetMockDIDDoc(t, false))
require.Error(t, err)
require.True(t, errors.Is(err, expected))
})
@@ -1428,7 +1432,7 @@ func TestPrepareResponse(t *testing.T) {
ctx.kms = &mockkms.KeyManager{GetKeyValue: mockKey}
- _, err = ctx.prepareResponse(request, mockdiddoc.GetMockDIDDoc(t))
+ _, err = ctx.prepareResponse(request, mockdiddoc.GetMockDIDDoc(t, false))
require.Error(t, err)
})
}
@@ -1439,7 +1443,7 @@ func TestContext_DIDDocAttachment(t *testing.T) {
t.Run("successful new did doc attachment without signing", func(t *testing.T) {
ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, transport.MediaTypeRFC0019EncryptedEnvelope)
- doc := mockdiddoc.GetMockDIDDoc(t)
+ doc := mockdiddoc.GetMockDIDDoc(t, false)
att, err := ctx.didDocAttachment(doc, "")
require.NoError(t, err)
@@ -1458,7 +1462,7 @@ func TestContext_DIDDocAttachment(t *testing.T) {
ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, transport.MediaTypeRFC0019EncryptedEnvelope)
ctx.doACAPyInterop = true
- doc := mockdiddoc.GetMockDIDDoc(t)
+ doc := mockdiddoc.GetMockDIDDoc(t, false)
_, pub, err := ctx.kms.CreateAndExportPubKeyBytes(kms.ED25519Type)
require.NoError(t, err)
@@ -1482,7 +1486,7 @@ func TestContext_DIDDocAttachment(t *testing.T) {
ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, transport.MediaTypeRFC0019EncryptedEnvelope)
ctx.doACAPyInterop = true
- doc := mockdiddoc.GetMockDIDDoc(t)
+ doc := mockdiddoc.GetMockDIDDoc(t, false)
_, err := ctx.didDocAttachment(doc, "did:key:not a did key")
require.Error(t, err)
@@ -1493,7 +1497,7 @@ func TestContext_DIDDocAttachment(t *testing.T) {
ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, transport.MediaTypeRFC0019EncryptedEnvelope)
ctx.doACAPyInterop = true
- doc := mockdiddoc.GetMockDIDDoc(t)
+ doc := mockdiddoc.GetMockDIDDoc(t, false)
didKey, _ := fingerprint.CreateDIDKey([]byte("abcdefghabcdefghabcdefghabcdefgh~!@#"))
@@ -1519,7 +1523,7 @@ func TestResolvePublicKey(t *testing.T) {
t.Run("resolve key reference from doc in vdr", func(t *testing.T) {
ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, transport.MediaTypeRFC0019EncryptedEnvelope)
- doc := mockdiddoc.GetMockDIDDoc(t)
+ doc := mockdiddoc.GetMockDIDDoc(t, false)
ctx.vdRegistry = &mockvdr.MockVDRegistry{ResolveValue: doc}
vm := doc.VerificationMethod[0]
@@ -1547,7 +1551,7 @@ func TestResolvePublicKey(t *testing.T) {
t.Run("fail to resolve doc for key reference", func(t *testing.T) {
ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, transport.MediaTypeRFC0019EncryptedEnvelope)
- doc := mockdiddoc.GetMockDIDDoc(t)
+ doc := mockdiddoc.GetMockDIDDoc(t, false)
vm := doc.VerificationMethod[0]
@@ -1558,7 +1562,7 @@ func TestResolvePublicKey(t *testing.T) {
t.Run("fail to find key in resolved doc", func(t *testing.T) {
ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, transport.MediaTypeRFC0019EncryptedEnvelope)
- doc := mockdiddoc.GetMockDIDDoc(t)
+ doc := mockdiddoc.GetMockDIDDoc(t, false)
ctx.vdRegistry = &mockvdr.MockVDRegistry{ResolveValue: doc}
kid := doc.VerificationMethod[0].ID
@@ -1578,7 +1582,7 @@ func TestResolveDIDDocFromMessage(t *testing.T) {
for _, mtp := range mtps {
t.Run(fmt.Sprintf("success with media type profile: %s", mtp), func(t *testing.T) {
ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, mtp)
- docIn := mockdiddoc.GetMockDIDDoc(t)
+ docIn := mockdiddoc.GetMockDIDDoc(t, false)
att, err := ctx.didDocAttachment(docIn, "")
require.NoError(t, err)
@@ -1591,7 +1595,7 @@ func TestResolveDIDDocFromMessage(t *testing.T) {
t.Run(fmt.Sprintf("success - public resolution with media type profile: %s", mtp), func(t *testing.T) {
ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, mtp)
- docIn := mockdiddoc.GetMockDIDDoc(t)
+ docIn := mockdiddoc.GetMockDIDDoc(t, false)
docIn.ID = "did:remote:abc"
ctx.vdRegistry = &mockvdr.MockVDRegistry{ResolveValue: docIn}
@@ -1605,7 +1609,7 @@ func TestResolveDIDDocFromMessage(t *testing.T) {
t.Run(fmt.Sprintf("failure - can't do public resolution with media type profile: %s", mtp),
func(t *testing.T) {
ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, mtp)
- docIn := mockdiddoc.GetMockDIDDoc(t)
+ docIn := mockdiddoc.GetMockDIDDoc(t, false)
docIn.ID = "did:remote:abc"
ctx.vdRegistry = &mockvdr.MockVDRegistry{ResolveErr: fmt.Errorf("resolve error")}
@@ -1659,7 +1663,7 @@ func TestResolveDIDDocFromMessage(t *testing.T) {
t.Run(fmt.Sprintf("success - interop mode with media type profile: %s", mtp), func(t *testing.T) {
ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, mtp)
- docIn := mockdiddoc.GetMockDIDDoc(t)
+ docIn := mockdiddoc.GetMockDIDDoc(t, false)
docIn.ID = "did:sov:abcdefg"
att, err := ctx.didDocAttachment(docIn, "")
@@ -1679,7 +1683,7 @@ func TestResolveDIDDocFromMessage(t *testing.T) {
ctx.vdRegistry = &mockvdr.MockVDRegistry{CreateErr: fmt.Errorf("create error")}
- docIn := mockdiddoc.GetMockDIDDoc(t)
+ docIn := mockdiddoc.GetMockDIDDoc(t, false)
att, err := ctx.didDocAttachment(docIn, "")
require.NoError(t, err)
@@ -1732,7 +1736,7 @@ func TestGetInvitationRecipientKey(t *testing.T) {
require.Equal(t, invitation.RecipientKeys[0], recKey)
})
t.Run("failed to get invitation recipient key", func(t *testing.T) {
- doc := mockdiddoc.GetMockDIDDoc(t)
+ doc := mockdiddoc.GetMockDIDDoc(t, false)
_, ok := diddoc.LookupService(doc, "did-communication")
require.True(t, ok)
ctx := context{vdRegistry: &mockvdr.MockVDRegistry{ResolveValue: doc}}
@@ -1835,7 +1839,7 @@ func TestGetDIDDocAndConnection(t *testing.T) {
customKMS := newKMS(t, mockstorage.NewMockStoreProvider())
ctx := context{
kms: customKMS,
- vdRegistry: &mockvdr.MockVDRegistry{CreateValue: mockdiddoc.GetMockDIDDoc(t)},
+ vdRegistry: &mockvdr.MockVDRegistry{CreateValue: mockdiddoc.GetMockDIDDoc(t, false)},
connectionRecorder: connRec,
connectionStore: didConnStore,
routeSvc: &mockroute.MockMediatorSvc{},
@@ -1871,7 +1875,7 @@ func TestGetDIDDocAndConnection(t *testing.T) {
customKMS := newKMS(t, mockstorage.NewMockStoreProvider())
ctx := context{
kms: customKMS,
- vdRegistry: &mockvdr.MockVDRegistry{CreateValue: mockdiddoc.GetMockDIDDoc(t)},
+ vdRegistry: &mockvdr.MockVDRegistry{CreateValue: mockdiddoc.GetMockDIDDoc(t, false)},
connectionRecorder: connRec,
routeSvc: &mockroute.MockMediatorSvc{
Connections: []string{"xyz"},
@@ -1890,7 +1894,7 @@ func TestGetDIDDocAndConnection(t *testing.T) {
customKMS := newKMS(t, mockstorage.NewMockStoreProvider())
ctx := context{
kms: customKMS,
- vdRegistry: &mockvdr.MockVDRegistry{CreateValue: mockdiddoc.GetMockDIDDoc(t)},
+ vdRegistry: &mockvdr.MockVDRegistry{CreateValue: mockdiddoc.GetMockDIDDoc(t, false)},
connectionRecorder: connRec,
routeSvc: &mockroute.MockMediatorSvc{
Connections: []string{"xyz"},
@@ -1944,7 +1948,7 @@ func TestGetServiceBlock(t *testing.T) {
vdRegistry: v,
}
- inv := newOOBInvite(doc.ID)
+ inv := newOOBInvite([]string{transport.MediaTypeRFC0019EncryptedEnvelope}, doc.ID)
svc, err := ctx.getServiceBlock(inv)
require.NoError(t, err)
@@ -1956,7 +1960,7 @@ func TestGetServiceBlock(t *testing.T) {
vdRegistry: v,
}
- inv := newOOBInvite(doc.ID)
+ inv := newOOBInvite([]string{transport.MediaTypeRFC0019EncryptedEnvelope}, doc.ID)
svc, err := ctx.getServiceBlock(inv)
require.Error(t, err)
@@ -1975,7 +1979,7 @@ func TestGetServiceBlock(t *testing.T) {
doACAPyInterop: true,
}
- inv := newOOBInvite(doc.ID)
+ inv := newOOBInvite([]string{transport.MediaTypeRFC0019EncryptedEnvelope}, doc.ID)
svc, err := ctx.getServiceBlock(inv)
require.Error(t, err)
@@ -1997,7 +2001,7 @@ func TestGetVerKey(t *testing.T) {
t.Run("returns verkey from explicit oob invitation", func(t *testing.T) {
expected := newServiceBlock([]string{encKey}, []string{encKey}, didCommServiceType)
- invitation := newOOBInvite(expected)
+ invitation := newOOBInvite(expected.Accept, expected)
ctx.connectionRecorder = connRecorder(t, testProvider())
err := ctx.connectionRecorder.SaveInvitation(invitation.ThreadID, invitation)
@@ -2008,7 +2012,9 @@ func TestGetVerKey(t *testing.T) {
require.Equal(t, expected.RecipientKeys[0], result)
expected = newServiceBlock([]string{encKey}, []string{encKey}, didCommV2ServiceType)
- invitation = newOOBInvite(expected)
+ accept, err := expected.ServiceEndpoint.Accept()
+ require.NoError(t, err)
+ invitation = newOOBInvite(accept, expected)
ctx.connectionRecorder = connRecorder(t, testProvider())
err = ctx.connectionRecorder.SaveInvitation(invitation.ThreadID, invitation)
@@ -2020,7 +2026,7 @@ func TestGetVerKey(t *testing.T) {
})
t.Run("returns verkey from implicit oob invitation", func(t *testing.T) {
publicDID := createDIDDoc(t, ctx)
- invitation := newOOBInvite(publicDID.ID)
+ invitation := newOOBInvite([]string{ctx.mediaTypeProfiles[0]}, publicDID.ID)
ctx.connectionRecorder = connRecorder(t, testProvider())
ctx.vdRegistry = &mockvdr.MockVDRegistry{
ResolveValue: publicDID,
@@ -2037,7 +2043,7 @@ func TestGetVerKey(t *testing.T) {
t.Run("returns verkey from implicit (interop) oob invitation", func(t *testing.T) {
publicDID, err := diddoc.ParseDocument([]byte(sovDoc))
require.NoError(t, err)
- invitation := newOOBInvite(publicDID.ID)
+ invitation := newOOBInvite([]string{transport.MediaTypeRFC0019EncryptedEnvelope}, publicDID.ID)
ctx.connectionRecorder = connRecorder(t, testProvider())
ctx.vdRegistry = &mockvdr.MockVDRegistry{
ResolveValue: publicDID,
@@ -2056,7 +2062,7 @@ func TestGetVerKey(t *testing.T) {
t.Run("returns verkey from explicit didexchange invitation", func(t *testing.T) {
expected := newServiceBlock([]string{encKey}, []string{encKey}, didCommServiceType)
- invitation := newDidExchangeInvite("", expected)
+ invitation := newDidExchangeInvite(t, "", expected)
ctx.connectionRecorder = connRecorder(t, testProvider())
err := ctx.connectionRecorder.SaveInvitation(invitation.ID, invitation)
@@ -2067,7 +2073,7 @@ func TestGetVerKey(t *testing.T) {
require.Equal(t, expected.RecipientKeys[0], result)
expected = newServiceBlock([]string{encKey}, []string{encKey}, didCommV2ServiceType)
- invitation = newDidExchangeInvite("", expected)
+ invitation = newDidExchangeInvite(t, "", expected)
ctx.connectionRecorder = connRecorder(t, testProvider())
err = ctx.connectionRecorder.SaveInvitation(invitation.ID, invitation)
@@ -2094,7 +2100,7 @@ func TestGetVerKey(t *testing.T) {
})
t.Run("fails for oob invitation with no target", func(t *testing.T) {
- invalid := newOOBInvite(nil)
+ invalid := newOOBInvite(nil, nil)
ctx.connectionRecorder = connRecorder(t, testProvider())
err := ctx.connectionRecorder.SaveInvitation(invalid.ThreadID, invalid)
@@ -2115,11 +2121,13 @@ func TestGetVerKey(t *testing.T) {
}
ctx.connectionRecorder = connRecorder(t, pr)
- invitation := newOOBInvite(newServiceBlock([]string{encKey}, []string{encKey}, didCommServiceType))
+ invitation := newOOBInvite([]string{transport.MediaTypeRFC0019EncryptedEnvelope},
+ newServiceBlock([]string{encKey}, []string{encKey}, didCommServiceType))
err := ctx.connectionRecorder.SaveInvitation(invitation.ID, invitation)
require.NoError(t, err)
- invitation = newOOBInvite(newServiceBlock([]string{encKey}, []string{encKey}, didCommV2ServiceType))
+ invitation = newOOBInvite([]string{transport.MediaTypeDIDCommV2Profile},
+ newServiceBlock([]string{encKey}, []string{encKey}, didCommV2ServiceType))
err = ctx.connectionRecorder.SaveInvitation(invitation.ID, invitation)
require.NoError(t, err)
@@ -2179,29 +2187,38 @@ func createDIDDocWithKey(verDIDKey, encDIDKey, mediaTypeProfile string) *diddoc.
var (
didCommService string
recKey string
+ sp commonmodel.Endpoint
)
switch mediaTypeProfile {
case transport.MediaTypeDIDCommV2Profile, transport.MediaTypeAIP2RFC0587Profile:
didCommService = vdrapi.DIDCommV2ServiceType
recKey = verDIDKey
+ sp = commonmodel.NewDIDCommV2Endpoint([]commonmodel.DIDCommV2Endpoint{
+ {URI: "http://localhost:58416", Accept: []string{mediaTypeProfile}},
+ })
default:
didCommService = vdrapi.DIDCommServiceType
recKey = encPubKeyID
+ sp = commonmodel.NewDIDCommV1Endpoint("http://localhost:58416")
}
services := []diddoc.Service{
{
- ID: fmt.Sprintf(didServiceID, id, 1),
- Type: didCommService,
- ServiceEndpoint: commonmodel.Endpoint{
- URI: "http://localhost:58416",
- Accept: []string{mediaTypeProfile},
- },
- Priority: 0,
- RecipientKeys: []string{recKey},
+ ID: fmt.Sprintf(didServiceID, id, 1),
+ Type: didCommService,
+ ServiceEndpoint: sp,
+ Priority: 0,
+ RecipientKeys: []string{recKey},
},
}
+
+ switch mediaTypeProfile {
+ case transport.MediaTypeDIDCommV2Profile, transport.MediaTypeAIP2RFC0587Profile:
+ default: // set DIDComm V1 Accept field.
+ services[0].Accept = []string{mediaTypeProfile}
+ }
+
createdTime := time.Now()
didDoc := &diddoc.Doc{
Context: []string{diddoc.ContextV1},
@@ -2360,7 +2377,9 @@ func toBytes(t *testing.T, data interface{}) []byte {
return src
}
-func newDidExchangeInvite(publicDID string, svc *diddoc.Service) *Invitation {
+func newDidExchangeInvite(t *testing.T, publicDID string, svc *diddoc.Service) *Invitation {
+ t.Helper()
+
i := &Invitation{
ID: uuid.New().String(),
Type: InvitationMsgType,
@@ -2368,35 +2387,70 @@ func newDidExchangeInvite(publicDID string, svc *diddoc.Service) *Invitation {
}
if svc != nil {
- i.RecipientKeys = svc.RecipientKeys
- i.ServiceEndpoint = svc.ServiceEndpoint.URI
- i.RoutingKeys = svc.ServiceEndpoint.RoutingKeys
+ if svc.Type == didCommV2ServiceType {
+ i.RecipientKeys = svc.RecipientKeys
+ uri, err := svc.ServiceEndpoint.URI()
+ require.NoError(t, err)
+
+ i.ServiceEndpoint = uri
+
+ routingKeys, err := svc.ServiceEndpoint.RoutingKeys()
+ require.NoError(t, err)
+
+ i.RoutingKeys = routingKeys
+ } else {
+ var err error
+
+ i.RecipientKeys = svc.RecipientKeys
+ i.ServiceEndpoint, err = svc.ServiceEndpoint.URI()
+ require.NoError(t, err)
+ i.RoutingKeys = svc.RoutingKeys
+ }
}
return i
}
-func newOOBInvite(target interface{}) *OOBInvitation {
+func newOOBInvite(accept []string, target interface{}) *OOBInvitation {
return &OOBInvitation{
ID: uuid.New().String(),
Type: oobMsgType,
ThreadID: uuid.New().String(),
TheirLabel: "test",
Target: target,
- MediaTypeProfiles: []string{"didcomm/v2"},
+ MediaTypeProfiles: accept,
}
}
func newServiceBlock(recKeys, routingKeys []string, didCommServiceVType string) *diddoc.Service {
- return &diddoc.Service{
- ID: uuid.New().String(),
- Type: didCommServiceVType,
- RecipientKeys: recKeys,
- ServiceEndpoint: commonmodel.Endpoint{
- URI: "http://test.com",
- RoutingKeys: routingKeys,
- },
+ var (
+ sp commonmodel.Endpoint
+ didCommV1RoutingKeys []string
+ )
+
+ switch didCommServiceVType {
+ case didCommV2ServiceType:
+ sp = commonmodel.NewDIDCommV2Endpoint([]commonmodel.DIDCommV2Endpoint{
+ {URI: "http://test.com", Accept: []string{transport.MediaTypeDIDCommV2Profile}, RoutingKeys: routingKeys},
+ })
+ default:
+ sp = commonmodel.NewDIDCommV1Endpoint("http://test.com")
+ didCommV1RoutingKeys = routingKeys
+ }
+
+ svc := &diddoc.Service{
+ ID: uuid.New().String(),
+ Type: didCommServiceVType,
+ RecipientKeys: recKeys,
+ ServiceEndpoint: sp,
+ }
+
+ if didCommServiceVType == didCommServiceType {
+ svc.Accept = []string{transport.MediaTypeRFC0019EncryptedEnvelope}
+ svc.RoutingKeys = didCommV1RoutingKeys
}
+
+ return svc
}
func connRecorder(t *testing.T, p provider) *connection.Recorder {
diff --git a/pkg/didcomm/protocol/mediator/service_test.go b/pkg/didcomm/protocol/mediator/service_test.go
index 6e65edf06..965f008ea 100644
--- a/pkg/didcomm/protocol/mediator/service_test.go
+++ b/pkg/didcomm/protocol/mediator/service_test.go
@@ -835,7 +835,7 @@ func TestServiceForwardMsg(t *testing.T) {
if didID == invalidDID {
return nil, errors.New("invalid")
}
- return &did.DocResolution{DIDDocument: mockdiddoc.GetMockDIDDoc(t)}, nil
+ return &did.DocResolution{DIDDocument: mockdiddoc.GetMockDIDDoc(t, false)}, nil
},
},
})
@@ -888,7 +888,7 @@ func TestMessagePickup(t *testing.T) {
},
VDRegistryValue: &mockvdr.MockVDRegistry{
ResolveFunc: func(didID string, opts ...vdrapi.DIDMethodOption) (*did.DocResolution, error) {
- return &did.DocResolution{DIDDocument: mockdiddoc.GetMockDIDDoc(t)}, nil
+ return &did.DocResolution{DIDDocument: mockdiddoc.GetMockDIDDoc(t, false)}, nil
},
},
})
@@ -931,7 +931,7 @@ func TestMessagePickup(t *testing.T) {
},
VDRegistryValue: &mockvdr.MockVDRegistry{
ResolveFunc: func(didID string, opts ...vdrapi.DIDMethodOption) (doc *did.DocResolution, e error) {
- return &did.DocResolution{DIDDocument: mockdiddoc.GetMockDIDDoc(t)}, nil
+ return &did.DocResolution{DIDDocument: mockdiddoc.GetMockDIDDoc(t, false)}, nil
},
},
})
diff --git a/pkg/didcomm/protocol/outofband/service.go b/pkg/didcomm/protocol/outofband/service.go
index 0a0675ae8..7bcfd96ad 100644
--- a/pkg/didcomm/protocol/outofband/service.go
+++ b/pkg/didcomm/protocol/outofband/service.go
@@ -10,11 +10,13 @@ import (
"encoding/json"
"errors"
"fmt"
+ "strings"
"github.com/google/uuid"
"github.com/mitchellh/mapstructure"
"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/didcomm/common/service"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/decorator"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/didexchange"
@@ -927,6 +929,7 @@ func decodeDIDInvitationAndOOBInvitation(c *callback) (*didexchange.OOBInvitatio
return didInv, oobInv, nil
}
+//nolint:funlen,gocognit,gocyclo
func chooseTarget(svcs []interface{}) (interface{}, error) {
for i := range svcs {
switch svc := svcs[i].(type) {
@@ -941,8 +944,70 @@ func chooseTarget(svcs []interface{}) (interface{}, error) {
}
err = decoder.Decode(svc)
+ //nolint:nestif
if err != nil {
- return nil, fmt.Errorf("failed to decode service block : %w", err)
+ var targetErr *mapstructure.Error
+
+ if errors.As(err, &targetErr) {
+ for _, er := range targetErr.Errors {
+ // TODO this error check depend on mapstructure decoding 'ServiceEndpoint' section of service.
+ // TODO Find a better way to build it.
+ // if serviceEndpoint is a string, explicitly convert it using model.NewDIDCommV1Endpoint().
+ if strings.EqualFold(er, "'serviceEndpoint' expected a map, got 'string'") {
+ uri, ok := svc["serviceEndpoint"].(string)
+ if ok {
+ s.ServiceEndpoint = model.NewDIDCommV1Endpoint(uri)
+ return &s, nil
+ }
+ } else if strings.EqualFold(er, "'serviceEndpoint' expected a map, got 'slice'") {
+ // if serviceEndpoint is a slice, explicitly convert each entry using the following call:
+ // model.NewDIDCommV2Endpoint()
+ seps, ok := svc["serviceEndpoint"].([]interface{})
+ if ok {
+ var (
+ v2Endpoints []model.DIDCommV2Endpoint
+ errs []error
+ )
+
+ for _, sep := range seps {
+ var v2Endpoint model.DIDCommV2Endpoint
+
+ endpointDecoder, e := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
+ TagName: "json", Result: &v2Endpoint,
+ })
+ if e != nil {
+ errs = append(errs, fmt.Errorf("failed to initialize DIDComm V2 "+
+ "ServiceEndpoint decoder: %w, skipping", e))
+
+ continue
+ }
+
+ e = endpointDecoder.Decode(sep)
+ if e != nil {
+ errs = append(errs, fmt.Errorf("didComm V2 ServiceEndpoint decoding "+
+ "failed: %w, skipping", e))
+
+ continue
+ }
+
+ v2Endpoints = append(v2Endpoints, v2Endpoint)
+ }
+
+ if len(v2Endpoints) > 0 {
+ s.ServiceEndpoint = model.NewDIDCommV2Endpoint(v2Endpoints)
+ return &s, nil
+ }
+
+ if len(errs) > 0 {
+ return nil, fmt.Errorf("failed to decode DIDComm V2 service endpoint of "+
+ "service block: %v", errs)
+ }
+ }
+ }
+ }
+ }
+
+ return nil, fmt.Errorf("failed to decode service block : %w, svc: %#v", err, svc)
}
return &s, nil
diff --git a/pkg/didcomm/protocol/outofband/service_test.go b/pkg/didcomm/protocol/outofband/service_test.go
index 3e2de7ddd..87b09590a 100644
--- a/pkg/didcomm/protocol/outofband/service_test.go
+++ b/pkg/didcomm/protocol/outofband/service_test.go
@@ -142,6 +142,40 @@ func TestHandleInbound(t *testing.T) {
_, err := s.HandleInbound(service.NewDIDCommMsgMap(newInvitation()), service.NewDIDCommContext(myDID, theirDID, nil))
require.NoError(t, err)
})
+
+ t.Run("accepts out-of-band invitation messages with service as map[string]interface{} and serviceEndpoint as "+
+ "string (DIDCommV1)", func(t *testing.T) {
+ s := newAutoService(t, testProvider())
+ customServiceMap := map[string]interface{}{
+ "recipientKeys": []string{"did:key:123"},
+ "serviceEndpoint": "http://user.agent.aries.js.example.com:10081",
+ "type": "did-communication",
+ }
+ _, err := s.HandleInbound(service.NewDIDCommMsgMap(newInvitationWithService(customServiceMap)),
+ service.NewDIDCommContext(myDID, theirDID, nil))
+ require.NoError(t, err)
+ })
+
+ t.Run("accepts out-of-band invitation messages with service as map[string]interface{} and serviceEndpoint as "+
+ "list (DIDCommV2)", func(t *testing.T) {
+ s := newAutoService(t, testProvider())
+ customServiceMap := map[string]interface{}{
+ "recipientKeys": []string{"did:key:123"},
+ "serviceEndpoint": []interface{}{
+ map[string]interface{}{
+ "accept": []interface{}{
+ "didcomm/v2", "didcomm/aip2;env=rfc19", "didcomm/aip2;env=rfc587",
+ },
+ "uri": "https://alice.aries.example.com:8081",
+ },
+ },
+ "type": "DIDCommMessaging",
+ }
+ _, err := s.HandleInbound(service.NewDIDCommMsgMap(newInvitationWithService(customServiceMap)),
+ service.NewDIDCommContext(myDID, theirDID, nil))
+ require.NoError(t, err)
+ })
+
t.Run("rejects unsupported message types", func(t *testing.T) {
s, err := New(testProvider())
require.NoError(t, err)
@@ -978,14 +1012,12 @@ func TestChooseTarget(t *testing.T) {
})
t.Run("chooses a did service entry", func(t *testing.T) {
expected := &did.Service{
- ID: uuid.New().String(),
- Type: "did-communication",
- Priority: 0,
- RecipientKeys: []string{"my ver key"},
- ServiceEndpoint: commonmodel.Endpoint{
- URI: "my service endpoint",
- RoutingKeys: []string{"my routing key"},
- },
+ ID: uuid.New().String(),
+ Type: "did-communication",
+ Priority: 0,
+ RecipientKeys: []string{"my ver key"},
+ ServiceEndpoint: commonmodel.NewDIDCommV1Endpoint("my service endpoint"),
+ RoutingKeys: []string{"my routing key"},
}
result, err := chooseTarget([]interface{}{expected})
require.NoError(t, err)
@@ -993,14 +1025,12 @@ func TestChooseTarget(t *testing.T) {
})
t.Run("chooses a map-type service", func(t *testing.T) {
expected := map[string]interface{}{
- "id": uuid.New().String(),
- "type": "did-communication",
- "priority": uint(0),
- "recipientKeys": []string{"my ver key"},
- "serviceEndpoint": commonmodel.Endpoint{
- URI: "my service endpoint",
- RoutingKeys: []string{"my routing key"},
- },
+ "id": uuid.New().String(),
+ "type": "did-communication",
+ "priority": uint(0),
+ "recipientKeys": []string{"my ver key"},
+ "serviceEndpoint": commonmodel.NewDIDCommV1Endpoint("my service endpoint"),
+ "RoutingKeys": []string{"my routing key"},
}
svc, err := chooseTarget([]interface{}{expected})
require.NoError(t, err)
@@ -1029,13 +1059,17 @@ func testProvider() *protocol.MockProvider {
}
func newInvitation() *Invitation {
+ return newInvitationWithService("did:example:1235")
+}
+
+func newInvitationWithService(svc interface{}) *Invitation {
return &Invitation{
ID: uuid.New().String(),
Type: InvitationMsgType,
Label: "test",
Goal: "test",
GoalCode: "test",
- Services: []interface{}{"did:example:1235"},
+ Services: []interface{}{svc},
Protocols: []string{didexchange.PIURI},
Requests: []*decorator.Attachment{
{
diff --git a/pkg/didcomm/protocol/outofbandv2/service.go b/pkg/didcomm/protocol/outofbandv2/service.go
index a8feb21f2..47d464971 100644
--- a/pkg/didcomm/protocol/outofbandv2/service.go
+++ b/pkg/didcomm/protocol/outofbandv2/service.go
@@ -268,11 +268,9 @@ func (s *Service) AcceptInvitation(i *Invitation, opts ...AcceptOption) (string,
}
services = append(services, did.Service{
- ServiceEndpoint: model.Endpoint{
- URI: serviceEndpoint,
- Accept: s.myMediaTypeProfiles,
- RoutingKeys: routingKeys,
- },
+ ServiceEndpoint: model.NewDIDCommV2Endpoint([]model.DIDCommV2Endpoint{
+ {URI: serviceEndpoint, Accept: s.myMediaTypeProfiles, RoutingKeys: routingKeys},
+ }),
RecipientKeys: []string{recKey},
Type: vdrapi.DIDCommV2ServiceType,
})
diff --git a/pkg/didcomm/protocol/outofbandv2/service_test.go b/pkg/didcomm/protocol/outofbandv2/service_test.go
index e74118948..a61960034 100644
--- a/pkg/didcomm/protocol/outofbandv2/service_test.go
+++ b/pkg/didcomm/protocol/outofbandv2/service_test.go
@@ -226,7 +226,7 @@ func TestAcceptInvitation(t *testing.T) {
s.vdrRegistry = &mockvdr.MockVDRegistry{
ResolveFunc: func(id string, _ ...vdrapi.DIDMethodOption) (*did.DocResolution, error) {
return &did.DocResolution{
- DIDDocument: mockdiddoc.GetMockDIDDoc(t),
+ DIDDocument: mockdiddoc.GetMockDIDDoc(t, true),
}, nil
},
}
@@ -267,7 +267,7 @@ func TestAcceptInvitation(t *testing.T) {
},
ResolveFunc: func(id string, _ ...vdrapi.DIDMethodOption) (*did.DocResolution, error) {
return &did.DocResolution{
- DIDDocument: mockdiddoc.GetMockDIDDoc(t),
+ DIDDocument: mockdiddoc.GetMockDIDDoc(t, true),
}, nil
},
}
@@ -280,8 +280,11 @@ func TestAcceptInvitation(t *testing.T) {
docSvc, ok := did.LookupService(createdDoc, vdrapi.DIDCommV2ServiceType)
require.True(t, ok)
- require.Len(t, docSvc.ServiceEndpoint.RoutingKeys, 1)
- require.Equal(t, testKey, docSvc.ServiceEndpoint.RoutingKeys[0])
+ routingKeys, err := docSvc.ServiceEndpoint.RoutingKeys()
+ require.NoError(t, err)
+
+ require.Len(t, routingKeys, 1)
+ require.Equal(t, testKey, routingKeys[0])
})
t.Run("error fetching mediator config", func(t *testing.T) {
@@ -338,7 +341,7 @@ func TestAcceptInvitation(t *testing.T) {
},
ResolveFunc: func(id string, _ ...vdrapi.DIDMethodOption) (*did.DocResolution, error) {
return &did.DocResolution{
- DIDDocument: mockdiddoc.GetMockDIDDoc(t),
+ DIDDocument: mockdiddoc.GetMockDIDDoc(t, true),
}, nil
},
}
@@ -387,7 +390,7 @@ func TestAcceptInvitation(t *testing.T) {
s.vdrRegistry = &mockvdr.MockVDRegistry{
ResolveFunc: func(id string, _ ...vdrapi.DIDMethodOption) (*did.DocResolution, error) {
return &did.DocResolution{
- DIDDocument: mockdiddoc.GetMockDIDDoc(t),
+ DIDDocument: mockdiddoc.GetMockDIDDoc(t, true),
}, nil
},
}
diff --git a/pkg/didcomm/transport/http/outbound.go b/pkg/didcomm/transport/http/outbound.go
index ffd48cd1e..5bea1ab2b 100644
--- a/pkg/didcomm/transport/http/outbound.go
+++ b/pkg/didcomm/transport/http/outbound.go
@@ -92,7 +92,12 @@ func (cs *OutboundHTTPClient) Start(prov transport.Provider) error {
// Send sends a2a exchange data via HTTP (client side).
func (cs *OutboundHTTPClient) Send(data []byte, destination *service.Destination) (string, error) {
- resp, err := cs.client.Post(destination.ServiceEndpoint.URI, commContentType, bytes.NewBuffer(data))
+ uri, err := destination.ServiceEndpoint.URI()
+ if err != nil {
+ return "", fmt.Errorf("error getting ServiceEndpoint URI: %w", err)
+ }
+
+ resp, err := cs.client.Post(uri, commContentType, bytes.NewBuffer(data))
if err != nil {
logger.Errorf("posting DID envelope to agent failed [%s, %v]", destination.ServiceEndpoint, err)
return "", err
diff --git a/pkg/didcomm/transport/http/outbound_test.go b/pkg/didcomm/transport/http/outbound_test.go
index b211dbee0..bf6394caf 100644
--- a/pkg/didcomm/transport/http/outbound_test.go
+++ b/pkg/didcomm/transport/http/outbound_test.go
@@ -102,6 +102,6 @@ func TestOutboundHTTPTransport(t *testing.T) {
func prepareDestination(endPoint string) *service.Destination {
return &service.Destination{
- ServiceEndpoint: model.Endpoint{URI: endPoint},
+ ServiceEndpoint: model.NewDIDCommV1Endpoint(endPoint),
}
}
diff --git a/pkg/didcomm/transport/ws/outbound.go b/pkg/didcomm/transport/ws/outbound.go
index c0a5b8b80..926401f22 100644
--- a/pkg/didcomm/transport/ws/outbound.go
+++ b/pkg/didcomm/transport/ws/outbound.go
@@ -86,14 +86,16 @@ func (cs *OutboundClient) AcceptRecipient(keys []string) bool {
return acceptRecipient(cs.pool, keys)
}
-//nolint:gocyclo
+//nolint:gocyclo,funlen
func (cs *OutboundClient) getConnection(destination *service.Destination) (*websocket.Conn, func(), error) {
var conn *websocket.Conn
// get the connection for the routing or recipient keys
keys := destination.RecipientKeys
- if len(destination.ServiceEndpoint.RoutingKeys) != 0 {
- keys = destination.ServiceEndpoint.RoutingKeys
+ if routingKeys, err := destination.ServiceEndpoint.RoutingKeys(); err == nil && len(routingKeys) != 0 {
+ keys = routingKeys
+ } else if len(destination.RoutingKeys) != 0 {
+ keys = destination.RoutingKeys
}
for _, v := range keys {
@@ -110,9 +112,17 @@ func (cs *OutboundClient) getConnection(destination *service.Destination) (*webs
return conn, cleanup, nil
}
- var err error
+ var (
+ err error
+ uri string
+ )
- conn, _, err = websocket.Dial(context.Background(), destination.ServiceEndpoint.URI, nil)
+ uri, err = destination.ServiceEndpoint.URI()
+ if err != nil {
+ return nil, cleanup, fmt.Errorf("unable to send ws outbound request: %w", err)
+ }
+
+ conn, _, err = websocket.Dial(context.Background(), uri, nil)
if err != nil {
return nil, cleanup, fmt.Errorf("websocket client : %w", err)
}
diff --git a/pkg/didcomm/transport/ws/outbound_test.go b/pkg/didcomm/transport/ws/outbound_test.go
index 499c6ddd5..96e358977 100644
--- a/pkg/didcomm/transport/ws/outbound_test.go
+++ b/pkg/didcomm/transport/ws/outbound_test.go
@@ -93,7 +93,7 @@ func TestClient(t *testing.T) {
addr := startWebSocketServer(t, echo)
resp, err := outbound.Send(createTransportDecRequest(t, decorator.TransportReturnRouteAll),
- prepareDestinationWithTransport("ws://"+addr, decorator.TransportReturnRouteAll, recKey))
+ prepareDestinationWithTransport("ws://"+addr, decorator.TransportReturnRouteAll, recKey, nil))
require.NoError(t, err)
require.Equal(t, "", resp)
@@ -125,8 +125,7 @@ func TestClient(t *testing.T) {
addr := startWebSocketServer(t, echo)
- des := prepareDestinationWithTransport("ws://"+addr, decorator.TransportReturnRouteAll, recKey)
- des.ServiceEndpoint.RoutingKeys = routingKeys
+ des := prepareDestinationWithTransport("ws://"+addr, decorator.TransportReturnRouteAll, recKey, routingKeys)
data := "didcomm-message"
resp, err := outbound.Send([]byte(data), des)
@@ -146,7 +145,7 @@ func TestClient(t *testing.T) {
addr := startWebSocketServer(t, echo)
resp, err := outbound.Send(createTransportDecRequest(t, decorator.TransportReturnRouteAll),
- prepareDestinationWithTransport("ws://"+addr, decorator.TransportReturnRouteAll, nil))
+ prepareDestinationWithTransport("ws://"+addr, decorator.TransportReturnRouteAll, nil, nil))
require.NoError(t, err)
require.Equal(t, "", resp)
})
@@ -163,7 +162,7 @@ func TestClient(t *testing.T) {
addr := startWebSocketServer(t, echo)
resp, err := outbound.Send(createTransportDecRequest(t, decorator.TransportReturnRouteNone),
- prepareDestinationWithTransport("ws://"+addr, decorator.TransportReturnRouteNone, nil))
+ prepareDestinationWithTransport("ws://"+addr, decorator.TransportReturnRouteNone, nil, nil))
require.NoError(t, err)
require.Equal(t, "", resp)
})
@@ -213,7 +212,7 @@ func TestClient(t *testing.T) {
require.NoError(t, err)
resp, err := outboundClient.Send([]byte("data"),
- prepareDestinationWithTransport("ws://"+addr, decorator.TransportReturnRouteAll, nil))
+ prepareDestinationWithTransport("ws://"+addr, decorator.TransportReturnRouteAll, nil, nil))
require.NoError(t, err)
require.Equal(t, "", resp)
diff --git a/pkg/didcomm/transport/ws/pool_test.go b/pkg/didcomm/transport/ws/pool_test.go
index 2a51718b0..a7cea62c7 100644
--- a/pkg/didcomm/transport/ws/pool_test.go
+++ b/pkg/didcomm/transport/ws/pool_test.go
@@ -59,7 +59,7 @@ func TestConnectionStore(t *testing.T) {
frameworkID: uuid.New().String(),
executeInbound: func(envelope *transport.Envelope) error {
resp, outboundErr := outbound.Send([]byte(response),
- prepareDestinationWithTransport("ws://doesnt-matter", "", []string{verKey}))
+ prepareDestinationWithTransport("ws://doesnt-matter", "", []string{verKey}, nil))
require.NoError(t, outboundErr)
require.Equal(t, "", resp)
return nil
@@ -125,7 +125,7 @@ func TestConnectionStore(t *testing.T) {
// send the outbound message
resp, err := outbound.Send(request,
- prepareDestinationWithTransport("ws://"+addr, decorator.TransportReturnRouteAll, []string{verKey}))
+ prepareDestinationWithTransport("ws://"+addr, decorator.TransportReturnRouteAll, []string{verKey}, nil))
require.NoError(t, err)
require.Equal(t, "", resp)
diff --git a/pkg/didcomm/transport/ws/support_test.go b/pkg/didcomm/transport/ws/support_test.go
index d6a44036e..d646ca68a 100644
--- a/pkg/didcomm/transport/ws/support_test.go
+++ b/pkg/didcomm/transport/ws/support_test.go
@@ -67,13 +67,15 @@ func websocketClient(t *testing.T, port string) (*websocket.Conn, func()) {
func prepareDestination(endPoint string) *service.Destination {
return &service.Destination{
- ServiceEndpoint: model.Endpoint{URI: endPoint},
+ ServiceEndpoint: model.NewDIDCommV1Endpoint(endPoint),
}
}
-func prepareDestinationWithTransport(endPoint, returnRoute string, recipientKeys []string) *service.Destination {
+func prepareDestinationWithTransport(endPoint, returnRoute string,
+ recipientKeys, routingKeys []string) *service.Destination {
return &service.Destination{
- ServiceEndpoint: model.Endpoint{URI: endPoint},
+ ServiceEndpoint: model.NewDIDCommV1Endpoint(endPoint),
+ RoutingKeys: routingKeys,
RecipientKeys: recipientKeys,
TransportReturnRoute: returnRoute,
}
diff --git a/pkg/doc/did/doc.go b/pkg/doc/did/doc.go
index 334a3dd6c..242683f6e 100644
--- a/pkg/doc/did/doc.go
+++ b/pkg/doc/did/doc.go
@@ -21,6 +21,7 @@ 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"
@@ -65,6 +66,7 @@ var (
schemaLoaderV1 = gojsonschema.NewStringLoader(schemaV1) //nolint:gochecknoglobals
schemaLoaderV011 = gojsonschema.NewStringLoader(schemaV011) //nolint:gochecknoglobals
schemaLoaderV12019 = gojsonschema.NewStringLoader(schemaV12019) //nolint:gochecknoglobals
+ logger = log.New("aries-framework/doc/did") //nolint:gochecknoglobals
)
// ErrDIDDocumentNotExist error did doc not exist.
@@ -366,7 +368,9 @@ type Service struct {
Type string `json:"type"`
Priority uint `json:"priority,omitempty"`
RecipientKeys []string `json:"recipientKeys,omitempty"`
+ RoutingKeys []string `json:"routingKeys,omitempty"`
ServiceEndpoint model.Endpoint `json:"serviceEndpoint"`
+ Accept []string `json:"accept,omitempty"`
Properties map[string]interface{} `json:"properties,omitempty"`
recipientKeysRelativeURL map[string]bool
routingKeysRelativeURL map[string]bool
@@ -634,14 +638,14 @@ func populateProofs(context, didID, baseURI string, rawProofs []interface{}) ([]
return proofs, nil
}
-//nolint:funlen
+//nolint:funlen,gocyclo
func populateServices(didID, baseURI string, rawServices []map[string]interface{}) []Service {
services := make([]Service, 0, len(rawServices))
for _, rawService := range rawServices {
id := stringEntry(rawService[jsonldID])
recipientKeys := stringArray(rawService[jsonldRecipientKeys])
- routingKeys := stringArray(rawService[jsonldRoutingKeys])
+ routingKeys := stringArray(rawService[jsonldRoutingKeys]) // routingkeys here for DIDComm V1 only.
var recipientKeysRelativeURL map[string]bool
@@ -662,28 +666,26 @@ func populateServices(didID, baseURI string, rawServices []map[string]interface{
routingKeys, routingKeysRelativeURL = populateKeys(routingKeys, didID, baseURI)
}
- sp := model.Endpoint{
- RoutingKeys: routingKeys,
- }
+ var sp model.Endpoint
//nolint:nestif
if epEntry, ok := rawService[jsonldServicePoint]; ok {
- var (
- uriStr string
- accept []string
- )
-
- if uriStr, ok = epEntry.(string); ok {
- sp.URI = uriStr
- } else {
- epMapEntry := mapEntry(epEntry)
-
- if uriStr, ok = epMapEntry["uri"].(string); ok {
- sp.URI = uriStr
- }
-
- if accept, ok = epMapEntry["accept"].([]string); ok {
- sp.Accept = accept
+ uriStr, ok := epEntry.(string)
+ // for now handling DIDComm V1 or V2 only.
+ if ok { // DIDComm V1 format.
+ sp = model.NewDIDCommV1Endpoint(uriStr)
+ } else if epEntry != nil { // DIDComm V2 format (first valid entry for now).
+ entries, ok := epEntry.([]interface{})
+ if ok && len(entries) > 0 {
+ firstEntry, ok := entries[0].(map[string]interface{})
+ if ok {
+ epURI := stringEntry(firstEntry["uri"])
+ epAccept := stringArray(firstEntry["accept"])
+ epRoutingKeys := stringArray(firstEntry["routingKeys"])
+ sp = model.NewDIDCommV2Endpoint([]model.DIDCommV2Endpoint{
+ {URI: epURI, Accept: epAccept, RoutingKeys: epRoutingKeys},
+ })
+ }
}
}
}
@@ -693,6 +695,7 @@ func populateServices(didID, baseURI string, rawServices []map[string]interface{
ServiceEndpoint: sp,
RecipientKeys: recipientKeys,
Priority: uintEntry(rawService[jsonldPriority]),
+ RoutingKeys: routingKeys,
recipientKeysRelativeURL: recipientKeysRelativeURL, routingKeysRelativeURL: routingKeysRelativeURL,
}
@@ -1026,7 +1029,11 @@ func stringEntry(entry interface{}) string {
return ""
}
- return entry.(string)
+ if e, ok := entry.(string); ok {
+ return e
+ }
+
+ return ""
}
// uintEntry.
@@ -1285,6 +1292,7 @@ func (r *didKeyResolver) Resolve(id string) (*verifier.PublicKey, error) {
// ErrKeyNotFound is returned when key is not found.
var ErrKeyNotFound = errors.New("key not found")
+// nolint:funlen,gocognit,gocyclo
func populateRawServices(services []Service, didID, baseURI string) []map[string]interface{} {
var rawServices []map[string]interface{}
@@ -1297,7 +1305,7 @@ func populateRawServices(services []Service, didID, baseURI string) []map[string
routingKeys := make([]string, 0)
- for _, v := range services[i].ServiceEndpoint.RoutingKeys {
+ for _, v := range services[i].RoutingKeys {
if services[i].routingKeysRelativeURL[v] {
routingKeys = append(routingKeys, makeRelativeDIDURL(v, baseURI, didID))
continue
@@ -1306,6 +1314,38 @@ func populateRawServices(services []Service, didID, baseURI string) []map[string
routingKeys = append(routingKeys, v)
}
+ sepRoutingKeys, err := services[i].ServiceEndpoint.RoutingKeys()
+ if err == nil && len(sepRoutingKeys) > 0 {
+ var tmpRoutingKeys []string
+
+ for _, v := range sepRoutingKeys {
+ if services[i].routingKeysRelativeURL[v] {
+ tmpRoutingKeys = append(tmpRoutingKeys, makeRelativeDIDURL(v, baseURI, didID))
+ continue
+ }
+
+ tmpRoutingKeys = append(tmpRoutingKeys, v)
+ }
+
+ sepRoutingKeys = tmpRoutingKeys
+ }
+
+ sepAccept, err := services[i].ServiceEndpoint.Accept()
+ if err != nil {
+ logger.Debugf("accept field of DIDComm V2 endpoint missing or invalid, it will be ignored: %w", err)
+ }
+
+ sepURI, err := services[i].ServiceEndpoint.URI()
+ if err != nil {
+ logger.Debugf("URI field of DIDComm V2 endpoint missing or invalid, it will be ignored: %w", err)
+ }
+
+ if len(sepAccept) > 0 || len(sepRoutingKeys) > 0 {
+ services[i].ServiceEndpoint = model.NewDIDCommV2Endpoint([]model.DIDCommV2Endpoint{
+ {URI: sepURI, Accept: sepAccept, RoutingKeys: sepRoutingKeys},
+ })
+ }
+
recipientKeys := make([]string, 0)
for _, v := range services[i].RecipientKeys {
@@ -1323,7 +1363,23 @@ func populateRawServices(services []Service, didID, baseURI string) []map[string
}
rawService[jsonldType] = services[i].Type
- rawService[jsonldServicePoint] = services[i].ServiceEndpoint
+
+ if len(sepAccept) > 0 || len(sepRoutingKeys) > 0 { // DIDComm V2
+ if len(sepAccept) == 0 { // ensure array is non nil, to avoid schema validation errors.
+ sepAccept = []string{}
+ }
+
+ if len(sepRoutingKeys) == 0 { // ensure array is non nil, to avoid schema validation errors.
+ sepRoutingKeys = []string{}
+ }
+
+ rawService[jsonldServicePoint] = []map[string]interface{}{
+ {"uri": sepURI, "accept": sepAccept, "routingKeys": sepRoutingKeys},
+ }
+ } else { // DIDComm V1
+ rawService[jsonldServicePoint] = sepURI
+ }
+
rawService[jsonldPriority] = services[i].Priority
if len(recipientKeys) > 0 {
diff --git a/pkg/doc/did/doc_test.go b/pkg/doc/did/doc_test.go
index aabb06b5d..b6e5277b6 100644
--- a/pkg/doc/did/doc_test.go
+++ b/pkg/doc/did/doc_test.go
@@ -144,19 +144,17 @@ func TestValidWithDocBase(t *testing.T) {
ID: "did:example:123456789abcdefghi#inbox",
Type: "SocialWebInboxService",
relativeURL: true,
- ServiceEndpoint: model.Endpoint{URI: "https://social.example.com/83hfh37dj"},
+ ServiceEndpoint: model.NewDIDCommV1Endpoint("https://social.example.com/83hfh37dj"),
Properties: map[string]interface{}{"spamCost": map[string]interface{}{"amount": "0.50", "currency": "USD"}},
},
{
- ID: "did:example:123456789abcdefghi#did-communication",
- Type: "did-communication",
- Priority: 0,
- relativeURL: true,
- RecipientKeys: []string{"did:example:123456789abcdefghi#key2"},
- ServiceEndpoint: model.Endpoint{
- URI: "https://agent.example.com/",
- RoutingKeys: []string{"did:example:123456789abcdefghi#key2"},
- },
+ ID: "did:example:123456789abcdefghi#did-communication",
+ Type: "did-communication",
+ Priority: 0,
+ relativeURL: true,
+ RecipientKeys: []string{"did:example:123456789abcdefghi#key2"},
+ RoutingKeys: []string{"did:example:123456789abcdefghi#key2"},
+ ServiceEndpoint: model.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},
@@ -253,18 +251,16 @@ func TestValid(t *testing.T) {
{
ID: "did:example:123456789abcdefghi#inbox",
Type: "SocialWebInboxService",
- ServiceEndpoint: model.Endpoint{URI: "https://social.example.com/83hfh37dj"},
+ ServiceEndpoint: model.NewDIDCommV1Endpoint("https://social.example.com/83hfh37dj"),
Properties: map[string]interface{}{"spamCost": map[string]interface{}{"amount": "0.50", "currency": "USD"}},
},
{
- ID: "did:example:123456789abcdefghi#did-communication",
- Type: "did-communication",
- Priority: 0,
- RecipientKeys: []string{"did:example:123456789abcdefghi#key2"},
- ServiceEndpoint: model.Endpoint{
- URI: "https://agent.example.com/",
- RoutingKeys: []string{"did:example:123456789abcdefghi#key2"},
- },
+ ID: "did:example:123456789abcdefghi#did-communication",
+ Type: "did-communication",
+ Priority: 0,
+ RecipientKeys: []string{"did:example:123456789abcdefghi#key2"},
+ RoutingKeys: []string{"did:example:123456789abcdefghi#key2"},
+ ServiceEndpoint: model.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},
diff --git a/pkg/doc/did/helpers_test.go b/pkg/doc/did/helpers_test.go
index 30a37bb64..365788840 100644
--- a/pkg/doc/did/helpers_test.go
+++ b/pkg/doc/did/helpers_test.go
@@ -16,7 +16,7 @@ import (
func TestGetRecipientKeys(t *testing.T) {
t.Run("successfully getting recipient keys", func(t *testing.T) {
- didDoc := mockdiddoc.GetMockDIDDoc(t)
+ didDoc := mockdiddoc.GetMockDIDDoc(t, false)
recipientKeys, ok := LookupDIDCommRecipientKeys(didDoc)
require.True(t, ok)
@@ -24,7 +24,7 @@ func TestGetRecipientKeys(t *testing.T) {
})
t.Run("error due to missing did-communication service", func(t *testing.T) {
- didDoc := mockdiddoc.GetMockDIDDoc(t)
+ didDoc := mockdiddoc.GetMockDIDDoc(t, false)
didDoc.Service = nil
recipientKeys, ok := LookupDIDCommRecipientKeys(didDoc)
@@ -33,7 +33,7 @@ func TestGetRecipientKeys(t *testing.T) {
})
t.Run("error due to missing recipient keys in did-communication service", func(t *testing.T) {
- didDoc := mockdiddoc.GetMockDIDDoc(t)
+ didDoc := mockdiddoc.GetMockDIDDoc(t, false)
didDoc.Service[0].RecipientKeys = []string{}
recipientKeys, ok := LookupDIDCommRecipientKeys(didDoc)
@@ -46,7 +46,7 @@ func TestGetDidCommService(t *testing.T) {
didCommServiceType := "did-communication"
t.Run("successfully getting did-communication service", func(t *testing.T) {
- didDoc := mockdiddoc.GetMockDIDDoc(t)
+ didDoc := mockdiddoc.GetMockDIDDoc(t, false)
s, ok := LookupService(didDoc, didCommServiceType)
require.True(t, ok)
@@ -55,7 +55,7 @@ func TestGetDidCommService(t *testing.T) {
})
t.Run("error due to missing service", func(t *testing.T) {
- didDoc := mockdiddoc.GetMockDIDDoc(t)
+ didDoc := mockdiddoc.GetMockDIDDoc(t, false)
didDoc.Service = nil
s, ok := LookupService(didDoc, didCommServiceType)
@@ -64,7 +64,7 @@ func TestGetDidCommService(t *testing.T) {
})
t.Run("error due to missing did-communication service", func(t *testing.T) {
- didDoc := mockdiddoc.GetMockDIDDoc(t)
+ didDoc := mockdiddoc.GetMockDIDDoc(t, false)
didDoc.Service[0].Type = "some-type"
s, ok := LookupService(didDoc, didCommServiceType)
diff --git a/pkg/doc/did/schema.go b/pkg/doc/did/schema.go
index 7b9cf36a6..10a6c298c 100644
--- a/pkg/doc/did/schema.go
+++ b/pkg/doc/did/schema.go
@@ -135,6 +135,32 @@ const (
}
}
},
+ "serviceEndpoint": {
+ "type": "object",
+ "minProperties": 1,
+ "properties": {
+ "uri": {
+ "type": "string",
+ "format": "uri"
+ },
+ "accept": {
+ "type": "array",
+ "items": [
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "routingKeys": {
+ "type": "array",
+ "items": [
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ },
"service": {
"required": [
"id",
@@ -152,22 +178,13 @@ const (
"serviceEndpoint": {
"oneOf": [
{
- "type": "object",
- "minProperties": 1,
- "properties": {
- "uri": {
- "type": "string",
- "format": "uri"
- },
- "accept": {
- "type": "array",
- "items": [
- {
- "type": "string"
- }
- ]
- }
- }
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/serviceEndpoint"
+ }
+ },
+ {
+ "type": "object"
},
{
"type": "string",
@@ -306,6 +323,32 @@ const (
}
}
},
+ "serviceEndpoint": {
+ "type": "object",
+ "minProperties": 1,
+ "properties": {
+ "uri": {
+ "type": "string",
+ "format": "uri"
+ },
+ "accept": {
+ "type": "array",
+ "items": [
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "routingKeys": {
+ "type": "array",
+ "items": [
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ },
"service": {
"required": [
"id",
@@ -323,22 +366,13 @@ const (
"serviceEndpoint": {
"oneOf": [
{
- "type": "object",
- "minProperties": 1,
- "properties": {
- "uri": {
- "type": "string",
- "format": "uri"
- },
- "accept": {
- "type": "array",
- "items": [
- {
- "type": "string"
- }
- ]
- }
- }
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/serviceEndpoint"
+ }
+ },
+ {
+ "type": "object"
},
{
"type": "string",
@@ -448,6 +482,32 @@ const (
}
}
},
+ "serviceEndpoint": {
+ "type": "object",
+ "minProperties": 1,
+ "properties": {
+ "uri": {
+ "type": "string",
+ "format": "uri"
+ },
+ "accept": {
+ "type": "array",
+ "items": [
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "routingKeys": {
+ "type": "array",
+ "items": [
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ },
"service": {
"required": [
"type",
@@ -464,22 +524,13 @@ const (
"serviceEndpoint": {
"oneOf": [
{
- "type": "object",
- "minProperties": 1,
- "properties": {
- "uri": {
- "type": "string",
- "format": "uri"
- },
- "accept": {
- "type": "array",
- "items": [
- {
- "type": "string"
- }
- ]
- }
- }
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/serviceEndpoint"
+ }
+ },
+ {
+ "type": "object"
},
{
"type": "string",
diff --git a/pkg/doc/verifiable/credential_jwt_proof_test.go b/pkg/doc/verifiable/credential_jwt_proof_test.go
index 59264b7fa..4eaf62fd7 100644
--- a/pkg/doc/verifiable/credential_jwt_proof_test.go
+++ b/pkg/doc/verifiable/credential_jwt_proof_test.go
@@ -240,7 +240,7 @@ func createDIDKeyFetcher(t *testing.T, pub ed25519.PublicKey, didID string) Publ
{
ID: fmt.Sprintf(didServiceID, id, 1),
Type: "did-communication",
- ServiceEndpoint: model.Endpoint{URI: "http://localhost:47582"},
+ ServiceEndpoint: model.NewDIDCommV1Endpoint("http://localhost:47582"),
Priority: 0,
RecipientKeys: []string{pubKeyID},
},
diff --git a/pkg/framework/aries/framework_test.go b/pkg/framework/aries/framework_test.go
index f8699aa97..3e3ef179f 100644
--- a/pkg/framework/aries/framework_test.go
+++ b/pkg/framework/aries/framework_test.go
@@ -126,7 +126,7 @@ func TestFramework(t *testing.T) {
e := ctx.OutboundDispatcher().Send(
[]byte("Hello World"),
mockdiddoc.MockDIDKey(t),
- &service.Destination{ServiceEndpoint: model.Endpoint{URI: serverURL}},
+ &service.Destination{ServiceEndpoint: model.NewDIDCommV1Endpoint(serverURL)},
)
require.NoError(t, e)
})
@@ -584,11 +584,11 @@ func TestFramework(t *testing.T) {
require.NoError(t, err)
require.Equal(t, 2, len(aries.outboundTransports))
r, err := aries.outboundTransports[0].Send([]byte("data"),
- &service.Destination{ServiceEndpoint: model.Endpoint{URI: "url"}})
+ &service.Destination{ServiceEndpoint: model.NewDIDCommV1Endpoint("url")})
require.NoError(t, err)
require.Equal(t, "data", r)
r, err = aries.outboundTransports[1].Send([]byte("data1"),
- &service.Destination{ServiceEndpoint: model.Endpoint{URI: "url"}})
+ &service.Destination{ServiceEndpoint: model.NewDIDCommV1Endpoint("url")})
require.NoError(t, err)
require.Equal(t, "data1", r)
require.NoError(t, aries.Close())
diff --git a/pkg/framework/context/context_test.go b/pkg/framework/context/context_test.go
index 329de25f3..3dea55aba 100644
--- a/pkg/framework/context/context_test.go
+++ b/pkg/framework/context/context_test.go
@@ -770,12 +770,12 @@ func TestNewProvider(t *testing.T) {
require.NoError(t, err)
require.Len(t, prov.OutboundTransports(), 2)
r, err := prov.outboundTransports[0].Send([]byte("data"),
- &service.Destination{ServiceEndpoint: model.Endpoint{URI: "url"}},
+ &service.Destination{ServiceEndpoint: model.NewDIDCommV1Endpoint("url")},
)
require.NoError(t, err)
require.Equal(t, "data", r)
r, err = prov.outboundTransports[1].Send([]byte("data1"),
- &service.Destination{ServiceEndpoint: model.Endpoint{URI: "url"}})
+ &service.Destination{ServiceEndpoint: model.NewDIDCommV1Endpoint("url")})
require.NoError(t, err)
require.Equal(t, "data1", r)
})
diff --git a/pkg/mock/diddoc/mock_diddoc.go b/pkg/mock/diddoc/mock_diddoc.go
index 7a2245015..d05f5d809 100644
--- a/pkg/mock/diddoc/mock_diddoc.go
+++ b/pkg/mock/diddoc/mock_diddoc.go
@@ -15,27 +15,64 @@ import (
"github.com/hyperledger/aries-framework-go/pkg/common/model"
"github.com/hyperledger/aries-framework-go/pkg/doc/did"
+ "github.com/hyperledger/aries-framework-go/pkg/doc/jose/jwk"
"github.com/hyperledger/aries-framework-go/pkg/vdr/fingerprint"
)
// GetMockDIDDoc creates a mock DID Doc for testing.
-func GetMockDIDDoc(t *testing.T) *did.Doc {
+//nolint:funlen
+func GetMockDIDDoc(t *testing.T, isDIDCommV2 bool) *did.Doc {
t.Helper()
+ var keyAgreements []did.Verification
+
+ services := []did.Service{
+ {
+ ServiceEndpoint: model.NewDIDCommV1Endpoint("https://localhost:8090"),
+ RoutingKeys: []string{MockDIDKey(t)},
+ Type: "did-communication",
+ Priority: 0,
+ RecipientKeys: []string{MockDIDKey(t)},
+ },
+ }
+
+ if isDIDCommV2 {
+ services[0].ServiceEndpoint = model.NewDIDCommV2Endpoint([]model.DIDCommV2Endpoint{
+ {
+ URI: "https://localhost:8090",
+ Accept: []string{"didcomm/v2"},
+ RoutingKeys: []string{MockDIDKey(t)},
+ },
+ })
+ services[0].Type = "DIDCommMessaging"
+ services[0].RoutingKeys = nil
+ services[0].RecipientKeys = []string{"#key-2"}
+ x25519 := jwk.JWK{}
+
+ err := x25519.UnmarshalJSON([]byte(`{
+ "kty": "OKP",
+ "crv": "X25519",
+ "x": "EXXinkMxdA4zGmwpOOpbCXt6Ts6CwyXyEKI3jfHkS3k"
+ }`))
+ if err == nil {
+ keyBytes, err := x25519.MarshalJSON()
+ if err == nil {
+ keyAgreements = append(keyAgreements, did.Verification{
+ VerificationMethod: did.VerificationMethod{
+ ID: "did:example:123456789abcdefghi#key-2",
+ Type: "JSONWebKey2020",
+ Controller: "did:example:123456789abcdefghi",
+ Value: keyBytes,
+ },
+ })
+ }
+ }
+ }
+
return &did.Doc{
Context: []string{"https://w3id.org/did/v1"},
ID: "did:peer:123456789abcdefghi",
- Service: []did.Service{
- {
- ServiceEndpoint: model.Endpoint{
- URI: "https://localhost:8090",
- RoutingKeys: []string{MockDIDKey(t)},
- },
- Type: "did-communication",
- Priority: 0,
- RecipientKeys: []string{MockDIDKey(t)},
- },
- },
+ Service: services,
VerificationMethod: []did.VerificationMethod{
{
ID: "did:example:123456789abcdefghi#keys-1",
@@ -56,6 +93,7 @@ func GetMockDIDDoc(t *testing.T) *did.Doc {
Value: base58.Decode("H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"),
},
},
+ KeyAgreement: keyAgreements,
}
}
@@ -72,20 +110,16 @@ func GetLegacyInteropMockDIDDoc(t *testing.T, id string, ed25519PubKey []byte) *
ID: peerDID,
Service: []did.Service{
{
- ServiceEndpoint: model.Endpoint{
- URI: "https://localhost:8090",
- },
- Type: "did-communication",
- Priority: 0,
- RecipientKeys: []string{pubKeyBase58},
+ ServiceEndpoint: model.NewDIDCommV1Endpoint("https://localhost:8090"),
+ Type: "did-communication",
+ Priority: 0,
+ RecipientKeys: []string{pubKeyBase58},
},
{
- ServiceEndpoint: model.Endpoint{
- URI: "https://localhost:8090",
- },
- Type: "IndyAgent",
- Priority: 0,
- RecipientKeys: []string{pubKeyBase58},
+ ServiceEndpoint: model.NewDIDCommV1Endpoint("https://localhost:8090"),
+ Type: "IndyAgent",
+ Priority: 0,
+ RecipientKeys: []string{pubKeyBase58},
},
},
VerificationMethod: []did.VerificationMethod{
@@ -101,7 +135,7 @@ func GetLegacyInteropMockDIDDoc(t *testing.T, id string, ed25519PubKey []byte) *
// GetMockDIDDocWithKeyAgreements creates mock DID doc with KeyAgreements.
func GetMockDIDDocWithKeyAgreements(t *testing.T) *did.Doc {
- didDoc := GetMockDIDDoc(t)
+ didDoc := GetMockDIDDoc(t, false)
didDoc.KeyAgreement = []did.Verification{
{
@@ -136,10 +170,11 @@ func GetMockDIDDocWithDIDCommV2Bloc(t *testing.T, id string) *did.Doc {
ID: peerDID,
Service: []did.Service{
{
- ServiceEndpoint: model.Endpoint{
+ ServiceEndpoint: model.NewDIDCommV2Endpoint([]model.DIDCommV2Endpoint{{
URI: "https://localhost:8090",
+ Accept: []string{"didcomm/v2"},
RoutingKeys: []string{MockDIDKey(t)},
- },
+ }}),
Type: "DIDCommMessaging",
Priority: 0,
RecipientKeys: []string{MockDIDKey(t)},
@@ -197,13 +232,11 @@ func GetMockIndyDoc(t *testing.T) *did.Doc {
},
Service: []did.Service{
{
- ID: "did:sov:AyRHrP7u6rF1dKViGf5shA;indy",
- Type: "IndyAgent",
- Priority: 0,
- RecipientKeys: []string{"6SFxbqdqGKtVVmLvXDnq9JP4ziZCG2fJzETpMYHt1VNx"},
- ServiceEndpoint: model.Endpoint{
- URI: "https://localhost:8090",
- },
+ ID: "did:sov:AyRHrP7u6rF1dKViGf5shA;indy",
+ Type: "IndyAgent",
+ Priority: 0,
+ RecipientKeys: []string{"6SFxbqdqGKtVVmLvXDnq9JP4ziZCG2fJzETpMYHt1VNx"},
+ ServiceEndpoint: model.NewDIDCommV1Endpoint("https://localhost:8090"),
},
},
Authentication: []did.Verification{
diff --git a/pkg/mock/vdr/mock_registry.go b/pkg/mock/vdr/mock_registry.go
index 7b00cbc52..b54a70095 100644
--- a/pkg/mock/vdr/mock_registry.go
+++ b/pkg/mock/vdr/mock_registry.go
@@ -102,13 +102,11 @@ func createDefaultDID() *did.Doc {
}
service := did.Service{
- ID: "did:example:123456789abcdefghi#did-communication",
- Type: "did-communication",
- ServiceEndpoint: model.Endpoint{
- URI: "https://agent.example.com/",
- },
- RecipientKeys: []string{creator},
- Priority: 0,
+ ID: "did:example:123456789abcdefghi#did-communication",
+ Type: "did-communication",
+ ServiceEndpoint: model.NewDIDCommV1Endpoint("https://agent.example.com/"),
+ RecipientKeys: []string{creator},
+ Priority: 0,
}
signingKey := did.VerificationMethod{
diff --git a/pkg/store/connection/connection_lookup.go b/pkg/store/connection/connection_lookup.go
index 9496b502d..be5d07fb8 100644
--- a/pkg/store/connection/connection_lookup.go
+++ b/pkg/store/connection/connection_lookup.go
@@ -64,10 +64,12 @@ type Record struct {
MyDID string
ServiceEndPoint model.Endpoint // ServiceEndPoint is 'their' DIDComm service endpoint.
RecipientKeys []string // RecipientKeys holds 'their' DIDComm recipient keys.
+ RoutingKeys []string // RoutingKeys holds 'their' DIDComm routing keys.
InvitationID string
InvitationDID string
Implicit bool
Namespace string
+ MediaTypeProfiles []string
DIDCommVersion didcomm.Version
PeerDIDInitialState string
MyDIDRotation *DIDRotationRecord `json:"myDIDRotation,omitempty"`
diff --git a/pkg/store/did/didconnection_test.go b/pkg/store/did/didconnection_test.go
index 764686e64..0b16efefd 100644
--- a/pkg/store/did/didconnection_test.go
+++ b/pkg/store/did/didconnection_test.go
@@ -36,8 +36,8 @@ func TestBaseConnectionStore(t *testing.T) {
prov := ctx{
store: mockstorage.NewMockStoreProvider(),
vdr: &mockvdr.MockVDRegistry{
- CreateValue: mockdiddoc.GetMockDIDDoc(t),
- ResolveValue: mockdiddoc.GetMockDIDDoc(t),
+ CreateValue: mockdiddoc.GetMockDIDDoc(t, false),
+ ResolveValue: mockdiddoc.GetMockDIDDoc(t, false),
},
}
@@ -63,8 +63,8 @@ func TestBaseConnectionStore(t *testing.T) {
},
},
vdr: &mockvdr.MockVDRegistry{
- CreateValue: mockdiddoc.GetMockDIDDoc(t),
- ResolveValue: mockdiddoc.GetMockDIDDoc(t),
+ CreateValue: mockdiddoc.GetMockDIDDoc(t, false),
+ ResolveValue: mockdiddoc.GetMockDIDDoc(t, false),
},
})
require.NoError(t, err)
@@ -123,7 +123,7 @@ func TestBaseConnectionStore(t *testing.T) {
cs, err := NewConnectionStore(&prov)
require.NoError(t, err)
- err = cs.SaveDIDByResolving(mockdiddoc.GetMockDIDDoc(t).ID)
+ err = cs.SaveDIDByResolving(mockdiddoc.GetMockDIDDoc(t, false).ID)
require.NoError(t, err)
})
diff --git a/pkg/store/did/store_test.go b/pkg/store/did/store_test.go
index a17f98fdb..c92dad1b3 100644
--- a/pkg/store/did/store_test.go
+++ b/pkg/store/did/store_test.go
@@ -258,7 +258,7 @@ func createDIDDocWithKey(pub string) *did.Doc {
{
ID: fmt.Sprintf(didServiceID, id, 1),
Type: "did-communication",
- ServiceEndpoint: model.Endpoint{URI: "http://localhost:58416"},
+ ServiceEndpoint: model.NewDIDCommV1Endpoint("http://localhost:58416"),
Priority: 0,
RecipientKeys: []string{pubKeyID},
},
diff --git a/pkg/vdr/peer/creator.go b/pkg/vdr/peer/creator.go
index 037f331b0..09c3d5307 100644
--- a/pkg/vdr/peer/creator.go
+++ b/pkg/vdr/peer/creator.go
@@ -8,10 +8,14 @@ package peer
import (
"fmt"
+ "strings"
"time"
"github.com/google/uuid"
+ "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/didcomm/transport"
"github.com/hyperledger/aries-framework-go/pkg/doc/did"
vdrapi "github.com/hyperledger/aries-framework-go/pkg/framework/aries/api/vdr"
"github.com/hyperledger/aries-framework-go/pkg/vdr/fingerprint"
@@ -24,6 +28,8 @@ const (
x25519KeyAgreementKey2019 = "X25519KeyAgreementKey2019"
)
+var logger = log.New("aries-framework/pkg/vdr/peer")
+
// Create create new DID Document.
// TODO https://github.com/hyperledger/aries-framework-go/issues/2466
func (v *VDR) Create(didDoc *did.Doc, opts ...vdrapi.DIDMethodOption) (*did.DocResolution, error) {
@@ -61,7 +67,7 @@ func (v *VDR) Create(didDoc *did.Doc, opts ...vdrapi.DIDMethodOption) (*did.DocR
return &did.DocResolution{Context: []string{schemaResV1}, DIDDocument: didDoc}, nil
}
-//nolint: funlen,gocyclo
+//nolint: funlen,gocyclo,gocognit
func build(didDoc *did.Doc, docOpts *vdrapi.DIDMethodOpts) (*did.DocResolution, error) {
if len(didDoc.VerificationMethod) == 0 && len(didDoc.KeyAgreement) == 0 {
return nil, fmt.Errorf("verification method and key agreement are empty, at least one should be set")
@@ -89,13 +95,48 @@ func build(didDoc *did.Doc, docOpts *vdrapi.DIDMethodOpts) (*did.DocResolution,
didDoc.Service[i].Type = v
}
- if didDoc.Service[i].ServiceEndpoint.URI == "" && docOpts.Values[DefaultServiceEndpoint] != nil {
- v, ok := docOpts.Values[DefaultServiceEndpoint].(string)
- if !ok {
- return nil, fmt.Errorf("defaultServiceEndpoint not string")
- }
+ uri, e := didDoc.Service[i].ServiceEndpoint.URI()
+ if e != nil {
+ logger.Debugf("service endpoint URI returned error %w, ignoring..", e)
+ }
- didDoc.Service[i].ServiceEndpoint.URI = v
+ // nolint:nestif
+ if uri == "" && docOpts.Values[DefaultServiceEndpoint] != nil {
+ switch didDoc.Service[i].Type {
+ case vdrapi.DIDCommServiceType:
+ v, ok := docOpts.Values[DefaultServiceEndpoint].(string)
+ if !ok {
+ return nil, fmt.Errorf("defaultServiceEndpoint not string")
+ }
+
+ didDoc.Service[i].ServiceEndpoint = model.NewDIDCommV1Endpoint(v)
+ case vdrapi.DIDCommV2ServiceType:
+ epArrayEntry := stringArray(docOpts.Values[DefaultServiceEndpoint])
+
+ sp := model.Endpoint{}
+
+ if len(epArrayEntry) == 0 {
+ sp = model.NewDIDCommV2Endpoint([]model.DIDCommV2Endpoint{{}})
+ } else {
+ for _, ep := range epArrayEntry {
+ err = sp.UnmarshalJSON([]byte(ep))
+ if err != nil {
+ if strings.EqualFold(err.Error(), "endpoint data is not supported") {
+ // if unmarshall failed, then use as string.
+ sp = model.NewDIDCommV2Endpoint([]model.DIDCommV2Endpoint{
+ {URI: ep, Accept: []string{transport.MediaTypeDIDCommV2Profile}},
+ })
+ }
+
+ continue
+ }
+
+ break
+ }
+ }
+
+ didDoc.Service[i].ServiceEndpoint = sp
+ }
}
applyDIDCommKeys(i, didDoc)
@@ -148,6 +189,41 @@ func build(didDoc *did.Doc, docOpts *vdrapi.DIDMethodOpts) (*did.DocResolution,
return &did.DocResolution{DIDDocument: didDoc}, nil
}
+// stringEntry.
+func stringEntry(entry interface{}) string {
+ if entry == nil {
+ return ""
+ }
+
+ return entry.(string)
+}
+
+// stringArray.
+func stringArray(entry interface{}) []string {
+ if entry == nil {
+ return nil
+ }
+
+ entries, ok := entry.([]interface{})
+ if !ok {
+ if entryStr, ok := entry.(string); ok {
+ return []string{entryStr}
+ }
+
+ return nil
+ }
+
+ var result []string
+
+ for _, e := range entries {
+ if e != nil {
+ result = append(result, stringEntry(e))
+ }
+ }
+
+ return result
+}
+
func applyDIDCommKeys(i int, didDoc *did.Doc) {
if didDoc.Service[i].Type == vdrapi.DIDCommServiceType {
didKey, _ := fingerprint.CreateDIDKey(didDoc.VerificationMethod[0].Value)
diff --git a/pkg/vdr/peer/creator_test.go b/pkg/vdr/peer/creator_test.go
index e7bbc6edd..7649a9ce0 100644
--- a/pkg/vdr/peer/creator_test.go
+++ b/pkg/vdr/peer/creator_test.go
@@ -75,11 +75,9 @@ func TestDIDCreator(t *testing.T) {
routingKeys := []string{"abc", "xyz"}
docResolution, err := c.Create(
&did.Doc{VerificationMethod: []did.VerificationMethod{getSigningKey()}, Service: []did.Service{{
- ServiceEndpoint: model.Endpoint{
- URI: "request-endpoint",
- RoutingKeys: routingKeys,
- },
- Type: "request-type",
+ ServiceEndpoint: model.NewDIDCommV1Endpoint("request-endpoint"),
+ RoutingKeys: routingKeys,
+ Type: "request-type",
}}})
require.NoError(t, err)
@@ -88,8 +86,10 @@ func TestDIDCreator(t *testing.T) {
// verify service not empty, type and endpoint from request options
require.NotEmpty(t, docResolution.DIDDocument.Service)
require.Equal(t, "request-type", docResolution.DIDDocument.Service[0].Type)
- require.Equal(t, "request-endpoint", docResolution.DIDDocument.Service[0].ServiceEndpoint.URI)
- require.Equal(t, routingKeys, docResolution.DIDDocument.Service[0].ServiceEndpoint.RoutingKeys)
+ uri, err := docResolution.DIDDocument.Service[0].ServiceEndpoint.URI()
+ require.NoError(t, err)
+ require.Equal(t, "request-endpoint", uri)
+ require.Equal(t, routingKeys, docResolution.DIDDocument.Service[0].RoutingKeys)
})
t.Run("test request overrides with keyAgreement", func(t *testing.T) {
@@ -103,11 +103,9 @@ func TestDIDCreator(t *testing.T) {
docResolution, err := c.Create(
&did.Doc{
VerificationMethod: []did.VerificationMethod{sVM}, Service: []did.Service{{
- ServiceEndpoint: model.Endpoint{
- URI: "request-endpoint",
- RoutingKeys: routingKeys,
- },
- Type: "request-type",
+ ServiceEndpoint: model.NewDIDCommV1Endpoint("request-endpoint"),
+ RoutingKeys: routingKeys,
+ Type: "request-type",
}},
KeyAgreement: []did.Verification{eVM},
})
@@ -118,8 +116,9 @@ func TestDIDCreator(t *testing.T) {
// verify service not empty, type and endpoint from request options
require.NotEmpty(t, docResolution.DIDDocument.Service)
require.Equal(t, "request-type", docResolution.DIDDocument.Service[0].Type)
- require.Equal(t, "request-endpoint", docResolution.DIDDocument.Service[0].ServiceEndpoint.URI)
- require.Equal(t, routingKeys, docResolution.DIDDocument.Service[0].ServiceEndpoint.RoutingKeys)
+ uri, err := docResolution.DIDDocument.Service[0].ServiceEndpoint.URI()
+ require.NoError(t, err)
+ require.Equal(t, "request-endpoint", uri)
// verify KeyAgreement
require.Len(t, docResolution.DIDDocument.KeyAgreement, 1)
diff --git a/pkg/vdr/verifiable_compat_test.go b/pkg/vdr/verifiable_compat_test.go
index 32a1f6a90..a1fc60610 100644
--- a/pkg/vdr/verifiable_compat_test.go
+++ b/pkg/vdr/verifiable_compat_test.go
@@ -153,7 +153,7 @@ func createPeerDIDLikeDIDExchangeService(t *testing.T, a *context.Provider) *did
docResolution, err := a.VDRegistry().Create(
peer.DIDMethod, &did.Doc{
Service: []did.Service{
- {ServiceEndpoint: model.Endpoint{URI: "http://example.com/didcomm"}},
+ {ServiceEndpoint: model.NewDIDCommV1Endpoint("http://example.com/didcomm")},
},
VerificationMethod: []did.VerificationMethod{
authVM,
diff --git a/test/bdd/agent/agent_sdk_steps.go b/test/bdd/agent/agent_sdk_steps.go
index 7e5996e74..40f631eb0 100644
--- a/test/bdd/agent/agent_sdk_steps.go
+++ b/test/bdd/agent/agent_sdk_steps.go
@@ -470,6 +470,7 @@ func withDynamicEnvelopeParams() createAgentOption {
func (a *SDKSteps) getStoreProvider(agentID string) storage.Provider {
storeProv := leveldb.NewProvider(dbPath + "/" + agentID + uuid.New().String())
+
return storeProv
}
diff --git a/test/bdd/cmd/sidetree/main.go b/test/bdd/cmd/sidetree/main.go
index 616f33005..515edb9cd 100644
--- a/test/bdd/cmd/sidetree/main.go
+++ b/test/bdd/cmd/sidetree/main.go
@@ -12,6 +12,7 @@ import (
"fmt"
"os"
+ "github.com/hyperledger/aries-framework-go/pkg/common/model"
"github.com/hyperledger/aries-framework-go/pkg/doc/jose/jwk/jwksupport"
"github.com/hyperledger/aries-framework-go/test/bdd/pkg/sidetree"
)
@@ -54,7 +55,7 @@ func main() {
JWK: j,
RecoveryJWK: recoveryJWK,
UpdateJWK: updateJWK,
- ServiceEndpoint: os.Args[4],
+ ServiceEndpoint: model.NewDIDCommV1Endpoint(os.Args[4]),
})
if err != nil {
fmt.Println(err.Error())
diff --git a/test/bdd/features/aries_didcommv2_mediator_e2e_sdk.feature b/test/bdd/features/aries_didcommv2_mediator_e2e_sdk.feature
index 43182f818..59a643f07 100644
--- a/test/bdd/features/aries_didcommv2_mediator_e2e_sdk.feature
+++ b/test/bdd/features/aries_didcommv2_mediator_e2e_sdk.feature
@@ -9,6 +9,7 @@
Feature: DIDComm v2 Transport between two Agents through DIDComm v2 Routers [SDK]
# https://identity.foundation/didcomm-messaging/spec/#routing
+ @aries_didcommv2_router_sdk_allmediatypes_key_agreement
Scenario Outline: Decentralized Identifier(DID) Exchange between two Edge Agents(without Inbound, DIDComm v2 is one way only) through Routers
# DID Exchange between Alice and her Router
Given options "" "" ""
diff --git a/test/bdd/features/waci_issuance_didcomm_v1.feature b/test/bdd/features/waci_issuance_didcomm_v1.feature
index f8910a28c..dc56e1b6e 100644
--- a/test/bdd/features/waci_issuance_didcomm_v1.feature
+++ b/test/bdd/features/waci_issuance_didcomm_v1.feature
@@ -10,7 +10,7 @@
Feature: WACI Issuance (Go API, DIDComm V1 + Issue Credential V2)
Background:
- Given all agents are using Media Type Profiles "didcomm/aip1,didcomm/aip2;env=rfc19,didcomm/aip2;env=rfc587,didcomm/v2"
+ Given all agents are using Media Type Profiles "didcomm/aip1,didcomm/aip2;env=rfc19"
Given "Issuer" agent is running on "localhost" port "random" with http-binding did resolver url "${SIDETREE_URL}" which accepts did method "sidetree"
And "Holder" agent is running on "localhost" port "random" with http-binding did resolver url "${SIDETREE_URL}" which accepts did method "sidetree"
diff --git a/test/bdd/fixtures/sidetree-mock/.env b/test/bdd/fixtures/sidetree-mock/.env
index 1b8a4e9af..9e9bdb14e 100644
--- a/test/bdd/fixtures/sidetree-mock/.env
+++ b/test/bdd/fixtures/sidetree-mock/.env
@@ -11,5 +11,5 @@
COMPOSE_DIR=.
# sidetree mock
-SIDETREE_MOCK_FIXTURE_IMAGE=ghcr.io/trustbloc/sidetree-mock
-SIDETREE_MOCK_FIXTURE_IMAGE_TAG=0.6.0
+SIDETREE_MOCK_FIXTURE_IMAGE=ghcr.io/trustbloc-cicd/sidetree-mock
+SIDETREE_MOCK_FIXTURE_IMAGE_TAG=0.7.0-snapshot-799d4d5
diff --git a/test/bdd/pkg/didexchange/didexchange_controller_steps.go b/test/bdd/pkg/didexchange/didexchange_controller_steps.go
index 7ce347ebe..3b931dbfa 100644
--- a/test/bdd/pkg/didexchange/didexchange_controller_steps.go
+++ b/test/bdd/pkg/didexchange/didexchange_controller_steps.go
@@ -20,6 +20,7 @@ import (
"github.com/hyperledger/aries-framework-go/pkg/client/didexchange"
"github.com/hyperledger/aries-framework-go/pkg/common/log"
+ "github.com/hyperledger/aries-framework-go/pkg/common/model"
didexcmd "github.com/hyperledger/aries-framework-go/pkg/controller/command/didexchange"
cmdkms "github.com/hyperledger/aries-framework-go/pkg/controller/command/kms"
"github.com/hyperledger/aries-framework-go/pkg/doc/jose/jwk/jwksupport"
@@ -657,13 +658,16 @@ func (a *ControllerSteps) CreatePublicDIDWithKeyType( // nolint:funlen,gocyclo
JWK: j,
RecoveryJWK: recoveryJWK,
UpdateJWK: updateJWK,
- ServiceEndpoint: a.agentServiceEndpoints[destination],
+ ServiceEndpoint: model.NewDIDCommV1Endpoint(a.agentServiceEndpoints[destination]),
}
if isDIDCommV2 {
params.ServiceType = vdr.DIDCommV2ServiceType
params.EncryptionKey = encKey
params.EncKeyType = kms.KeyType(encKeyType)
+ params.ServiceEndpoint = model.NewDIDCommV2Endpoint([]model.DIDCommV2Endpoint{
+ {URI: a.agentServiceEndpoints[destination], Accept: []string{"didcomm/v2"}},
+ })
}
doc, err := sidetree.CreateDID(¶ms)
diff --git a/test/bdd/pkg/didresolver/didresolver_steps.go b/test/bdd/pkg/didresolver/didresolver_steps.go
index d6dec1122..37fd36d5c 100644
--- a/test/bdd/pkg/didresolver/didresolver_steps.go
+++ b/test/bdd/pkg/didresolver/didresolver_steps.go
@@ -16,6 +16,7 @@ import (
"github.com/cucumber/godog"
"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/didcomm/transport"
diddoc "github.com/hyperledger/aries-framework-go/pkg/doc/did"
"github.com/hyperledger/aries-framework-go/pkg/doc/jose/jwk/jwksupport"
@@ -113,6 +114,7 @@ func createDIDDocument(ctx *bddctx.BDDContext, agents, keyType string) error {
}
serviceType := vdrapi.DIDCommServiceType
+ serviceEndpoint := model.NewDIDCommV1Endpoint(ctx.AgentCtx[agentID].ServiceEndpoint())
mtps := ctx.AgentCtx[agentID].MediaTypeProfiles()
for _, mtp := range mtps {
@@ -122,6 +124,9 @@ func createDIDDocument(ctx *bddctx.BDDContext, agents, keyType string) error {
case transport.MediaTypeDIDCommV2Profile, transport.MediaTypeAIP2RFC0587Profile:
found = true
serviceType = vdrapi.DIDCommV2ServiceType
+ serviceEndpoint = model.NewDIDCommV2Endpoint([]model.DIDCommV2Endpoint{
+ {URI: ctx.AgentCtx[agentID].ServiceEndpoint()},
+ })
}
if found {
@@ -139,7 +144,7 @@ func createDIDDocument(ctx *bddctx.BDDContext, agents, keyType string) error {
EncryptionKey: encKey,
KeyType: keyType,
EncKeyType: encKT,
- ServiceEndpoint: ctx.AgentCtx[agentID].ServiceEndpoint(),
+ ServiceEndpoint: serviceEndpoint,
ServiceType: serviceType,
})
if err != nil {
diff --git a/test/bdd/pkg/sidetree/sidetree.go b/test/bdd/pkg/sidetree/sidetree.go
index 4215f245d..9696c2d89 100644
--- a/test/bdd/pkg/sidetree/sidetree.go
+++ b/test/bdd/pkg/sidetree/sidetree.go
@@ -16,6 +16,7 @@ import (
"github.com/trustbloc/sidetree-core-go/pkg/util/pubkey"
"github.com/trustbloc/sidetree-core-go/pkg/versions/1_0/client"
+ "github.com/hyperledger/aries-framework-go/pkg/common/model"
diddoc "github.com/hyperledger/aries-framework-go/pkg/doc/did"
"github.com/hyperledger/aries-framework-go/pkg/doc/jose/jwk"
"github.com/hyperledger/aries-framework-go/pkg/doc/util/jwkkid"
@@ -39,7 +40,7 @@ const docTemplate = `{
{
"id": "hub",
"type": "%s",
- "serviceEndpoint": "%s",
+ "serviceEndpoint": %s,
"recipientKeys" : [ "%s" ]
}
]
@@ -48,7 +49,7 @@ const docTemplate = `{
const (
sha2_256 = 18 // multihash
- defaultKeyType = "JwsVerificationKey2020"
+ defaultKeyType = "JsonWebKey2020"
)
type didResolution struct {
@@ -68,7 +69,7 @@ type CreateDIDParams struct {
EncryptionKey []byte
KeyType string
EncKeyType kms.KeyType
- ServiceEndpoint string
+ ServiceEndpoint model.Endpoint
ServiceType string
}
@@ -162,7 +163,12 @@ func getOpaqueDocument(params *CreateDIDParams) ([]byte, error) {
ka = fmt.Sprintf(ka, "key-2", kaType, encJWKMarshalled)
}
- data := fmt.Sprintf(docTemplate, params.KeyID, keyType, opsPubKey, ka, serviceType, params.ServiceEndpoint, didKey)
+ mEndPoint, err := params.ServiceEndpoint.MarshalJSON()
+ if err != nil {
+ return nil, err
+ }
+
+ data := fmt.Sprintf(docTemplate, params.KeyID, keyType, opsPubKey, ka, serviceType, mEndPoint, didKey)
doc, err := document.FromBytes([]byte(data))
if err != nil {
diff --git a/test/bdd/pkg/waci/waci_issuance_didcomm_v1_sdk_steps.go b/test/bdd/pkg/waci/waci_issuance_didcomm_v1_sdk_steps.go
index 9a13682ee..d92c13c72 100644
--- a/test/bdd/pkg/waci/waci_issuance_didcomm_v1_sdk_steps.go
+++ b/test/bdd/pkg/waci/waci_issuance_didcomm_v1_sdk_steps.go
@@ -570,7 +570,7 @@ func (i *IssuanceSDKDIDCommV1Steps) newInvitation(agentID string,
opts := []outofband.MessageOption{
outofband.WithLabel(agentID),
outofband.WithAttachments(attachDecorators...),
- outofband.WithAccept("didcomm/v2"),
+ outofband.WithAccept("didcomm/aip1", "JWM/1.0"),
}
inv, err := agent.CreateInvitation(
From 04bfea80427b3d2ae374ddad2ced84b77c70a179 Mon Sep 17 00:00:00 2001
From: Firas Qutishat
Date: Tue, 31 May 2022 21:24:02 +0300
Subject: [PATCH 38/54] chore: create didcomm v1 and v2 keys in mediator
service (#3247)
Signed-off-by: Firas Qutishat
---
.../packer/legacy/authcrypt/authcrypt_test.go | 12 ++---
pkg/didcomm/packer/legacy/authcrypt/pack.go | 17 +++++--
pkg/didcomm/protocol/mediator/service.go | 45 ++++++++++---------
pkg/didcomm/protocol/mediator/service_test.go | 1 +
4 files changed, 41 insertions(+), 34 deletions(-)
diff --git a/pkg/didcomm/packer/legacy/authcrypt/authcrypt_test.go b/pkg/didcomm/packer/legacy/authcrypt/authcrypt_test.go
index 41a5cdf03..ebd62206f 100644
--- a/pkg/didcomm/packer/legacy/authcrypt/authcrypt_test.go
+++ b/pkg/didcomm/packer/legacy/authcrypt/authcrypt_test.go
@@ -169,8 +169,7 @@ func TestEncrypt(t *testing.T) {
badKey := "6ZAQ7QpmR9EqhJdwx1jQsjq6nnpehwVqUbhVxiEiYEV7"
_, err := packer.Pack("", []byte("Test Message"), senderKey, [][]byte{base58.Decode(badKey)})
- require.EqualError(t, err, "pack: failed to build recipients: buildRecipients: failed to build "+
- "recipient: buildRecipient: failed to convert public Ed25519 to Curve25519: error converting public key")
+ require.EqualError(t, err, "pack: failed to build recipients: recipients keys are empty")
})
recipientKey := createKey(t, testingKMS)
@@ -181,8 +180,7 @@ func TestEncrypt(t *testing.T) {
_, err := packer.Pack("", []byte("Test Message"), []byte{1, 2, 3}, [][]byte{recipientKey})
require.Error(t, err)
- require.Contains(t, err.Error(), "getKeySet: failed to read json keyset from reader: cannot read data"+
- " for keysetID")
+ require.Contains(t, err.Error(), "recipients keys are empty")
})
t.Run("Success test case: given keys, generate envelope", func(t *testing.T) {
@@ -306,8 +304,7 @@ func TestEncryptComponents(t *testing.T) {
"", []byte(
"Lorem Ipsum Dolor Sit Amet Consectetur Adispici Elit"),
base58.Decode(senderPub), [][]byte{base58.Decode(rec1Pub)})
- require.EqualError(t, err, "pack: failed to build recipients: buildRecipients: failed to build "+
- "recipient: buildRecipient: failed to generate random nonce: mock Reader has failed intentionally")
+ require.EqualError(t, err, "pack: failed to build recipients: recipients keys are empty")
})
t.Run("Failure: recipient sodiumBoxSeal nonce generation fails", func(t *testing.T) {
@@ -318,8 +315,7 @@ func TestEncryptComponents(t *testing.T) {
"",
[]byte("Lorem Ipsum Dolor Sit Amet Consectetur Adispici Elit"),
base58.Decode(senderPub), [][]byte{base58.Decode(rec1Pub)})
- require.EqualError(t, err, "pack: failed to build recipients: buildRecipients: failed to build"+
- " recipient: buildRecipient: failed to encrypt sender key: mock Reader has failed intentionally")
+ require.EqualError(t, err, "pack: failed to build recipients: recipients keys are empty")
})
t.Run("Success: 4 reads necessary for pack", func(t *testing.T) {
diff --git a/pkg/didcomm/packer/legacy/authcrypt/pack.go b/pkg/didcomm/packer/legacy/authcrypt/pack.go
index 1400e9f13..23293d52d 100644
--- a/pkg/didcomm/packer/legacy/authcrypt/pack.go
+++ b/pkg/didcomm/packer/legacy/authcrypt/pack.go
@@ -16,12 +16,15 @@ import (
chacha "golang.org/x/crypto/chacha20poly1305"
"golang.org/x/crypto/poly1305"
+ "github.com/hyperledger/aries-framework-go/pkg/common/log"
"github.com/hyperledger/aries-framework-go/pkg/internal/cryptoutil"
"github.com/hyperledger/aries-framework-go/pkg/kms"
"github.com/hyperledger/aries-framework-go/pkg/kms/localkms"
"github.com/hyperledger/aries-framework-go/pkg/kms/webkms"
)
+var logger = log.New("aries-framework/pkg/didcomm/packer/legacy")
+
// Pack will encode the payload argument
// Using the protocol defined by Aries RFC 0019.
func (p *Packer) Pack(_ string, payload, sender []byte, recipientPubKeys [][]byte) ([]byte, error) {
@@ -101,15 +104,21 @@ func (p *Packer) buildEnvelope(nonce, payload, cek []byte, header *protected) ([
}
func (p *Packer) buildRecipients(cek *[chacha.KeySize]byte, senderKey []byte, recPubKeys [][]byte) ([]recipient, error) { // nolint: lll
- encodedRecipients := make([]recipient, len(recPubKeys))
+ encodedRecipients := make([]recipient, 0)
- for i, recKey := range recPubKeys {
+ for _, recKey := range recPubKeys {
rec, err := p.buildRecipient(cek, senderKey, recKey)
if err != nil {
- return nil, fmt.Errorf("buildRecipients: failed to build recipient: %w", err)
+ logger.Warnf("buildRecipients: failed to build recipient: %w", err)
+
+ continue
}
- encodedRecipients[i] = *rec
+ encodedRecipients = append(encodedRecipients, *rec)
+ }
+
+ if len(encodedRecipients) == 0 {
+ return nil, fmt.Errorf("recipients keys are empty")
}
return encodedRecipients, nil
diff --git a/pkg/didcomm/protocol/mediator/service.go b/pkg/didcomm/protocol/mediator/service.go
index 3c0c965e9..e1a29689e 100644
--- a/pkg/didcomm/protocol/mediator/service.go
+++ b/pkg/didcomm/protocol/mediator/service.go
@@ -22,7 +22,6 @@ import (
"github.com/hyperledger/aries-framework-go/pkg/didcomm/dispatcher"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/decorator"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/messagepickup"
- "github.com/hyperledger/aries-framework-go/pkg/didcomm/transport"
"github.com/hyperledger/aries-framework-go/pkg/doc/util/kmsdidkey"
"github.com/hyperledger/aries-framework-go/pkg/framework/aries/api/vdr"
"github.com/hyperledger/aries-framework-go/pkg/internal/logutil"
@@ -392,29 +391,31 @@ func (s *Service) handleInboundRequest(c *callback) error {
c.msg.ID(),
c.options,
s.endpoint,
- func() (string, error) {
- for _, mtp := range s.mediaTypeProfiles {
- switch mtp {
- case transport.MediaTypeDIDCommV2Profile, transport.MediaTypeAIP2RFC0587Profile:
- _, pubKeyBytes, e := s.kms.CreateAndExportPubKeyBytes(s.keyAgreementType)
- if e != nil {
- return "", fmt.Errorf("outboundGrant from handleInboundRequest: kms failed to create "+
- "and export %v key: %w", s.keyAgreementType, e)
- }
-
- return kmsdidkey.BuildDIDKeyByKeyType(pubKeyBytes, s.keyAgreementType)
+ func() ([]string, error) {
+ if len(s.mediaTypeProfiles) > 0 {
+ _, pubKeyBytes, e := s.kms.CreateAndExportPubKeyBytes(s.keyAgreementType)
+ if e != nil {
+ return nil, fmt.Errorf("outboundGrant from handleInboundRequest: kms failed to create "+
+ "and export %v key: %w", s.keyAgreementType, e)
}
- }
- _, pubKeyBytes, er := s.kms.CreateAndExportPubKeyBytes(kms.ED25519Type)
- if er != nil {
- return "", fmt.Errorf("outboundGrant from handleInboundRequest: kms failed to create and "+
- "export ED25519 key: %w", er)
- }
+ didCommV2Key, errBuild := kmsdidkey.BuildDIDKeyByKeyType(pubKeyBytes, s.keyAgreementType)
+ if errBuild != nil {
+ return nil, errBuild
+ }
- didKey, _ := fingerprint.CreateDIDKey(pubKeyBytes)
+ _, pubKeyBytes, er := s.kms.CreateAndExportPubKeyBytes(kms.ED25519Type)
+ if er != nil {
+ return nil, fmt.Errorf("outboundGrant from handleInboundRequest: kms failed to create and "+
+ "export ED25519 key: %w", er)
+ }
+
+ didKey, _ := fingerprint.CreateDIDKey(pubKeyBytes)
+
+ return []string{didKey, didCommV2Key}, nil
+ }
- return didKey, er
+ return nil, nil
},
)
if err != nil {
@@ -426,7 +427,7 @@ func (s *Service) handleInboundRequest(c *callback) error {
func outboundGrant(
msgID string, opts *Options,
- defaultEndpoint string, defaultKey func() (string, error)) (*Grant, error) {
+ defaultEndpoint string, defaultKey func() ([]string, error)) (*Grant, error) {
grant := &Grant{
ID: msgID,
Type: GrantMsgType,
@@ -444,7 +445,7 @@ func outboundGrant(
return nil, fmt.Errorf("outboundGrant: failed to create keys : %w", err)
}
- grant.RoutingKeys = []string{keys}
+ grant.RoutingKeys = keys
}
logger.Debugf("outbound grant: %+v", grant)
diff --git a/pkg/didcomm/protocol/mediator/service_test.go b/pkg/didcomm/protocol/mediator/service_test.go
index 965f008ea..a6382d332 100644
--- a/pkg/didcomm/protocol/mediator/service_test.go
+++ b/pkg/didcomm/protocol/mediator/service_test.go
@@ -338,6 +338,7 @@ func TestServiceRequestMsg(t *testing.T) {
CrAndExportPubKeyErr: expected,
},
OutboundDispatcherValue: &mockdispatcher.MockOutbound{},
+ MediaTypeProfilesValue: []string{"value"},
})
require.NoError(t, err)
From d25f6e2f8ab6f24d8be993cfc8d953a1d9619d5b Mon Sep 17 00:00:00 2001
From: Baha <29608896+Baha-sk@users.noreply.github.com>
Date: Thu, 2 Jun 2022 13:20:46 -0400
Subject: [PATCH 39/54] fix: did doc parsing to properly distinguish V1 vs V2
types (#3250)
Signed-off-by: Baha Shaaban
---
pkg/doc/did/doc.go | 23 +++++++++++++----------
pkg/doc/did/doc_test.go | 13 +++++++++++++
pkg/doc/did/testdata/valid_doc.jsonld | 7 +++++++
3 files changed, 33 insertions(+), 10 deletions(-)
diff --git a/pkg/doc/did/doc.go b/pkg/doc/did/doc.go
index 242683f6e..f07545306 100644
--- a/pkg/doc/did/doc.go
+++ b/pkg/doc/did/doc.go
@@ -60,6 +60,10 @@ const (
jsonldPublicKeyHex = "publicKeyHex"
jsonldPublicKeyPem = "publicKeyPem"
jsonldPublicKeyjwk = "publicKeyJwk"
+
+ // service type added here (to avoid cyclic dependency with vdrapi):
+ // didCommV2ServiceType is the DID Communications V2 service type.
+ didCommV2ServiceType = "DIDCommMessaging"
)
var (
@@ -1340,7 +1344,7 @@ 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 len(sepAccept) > 0 || len(sepRoutingKeys) > 0 {
+ if services[i].Type == didCommV2ServiceType {
services[i].ServiceEndpoint = model.NewDIDCommV2Endpoint([]model.DIDCommV2Endpoint{
{URI: sepURI, Accept: sepAccept, RoutingKeys: sepRoutingKeys},
})
@@ -1364,19 +1368,18 @@ func populateRawServices(services []Service, didID, baseURI string) []map[string
rawService[jsonldType] = services[i].Type
- if len(sepAccept) > 0 || len(sepRoutingKeys) > 0 { // DIDComm V2
- if len(sepAccept) == 0 { // ensure array is non nil, to avoid schema validation errors.
- sepAccept = []string{}
+ if services[i].Type == didCommV2ServiceType { // DIDComm V2
+ serviceEndpointMap := []map[string]interface{}{{"uri": sepURI}}
+ if len(sepAccept) > 0 {
+ serviceEndpointMap[0]["accept"] = sepAccept
}
- if len(sepRoutingKeys) == 0 { // ensure array is non nil, to avoid schema validation errors.
- sepRoutingKeys = []string{}
+ if len(sepRoutingKeys) > 0 {
+ serviceEndpointMap[0]["routingKeys"] = sepRoutingKeys
}
- rawService[jsonldServicePoint] = []map[string]interface{}{
- {"uri": sepURI, "accept": sepAccept, "routingKeys": sepRoutingKeys},
- }
- } else { // DIDComm V1
+ rawService[jsonldServicePoint] = serviceEndpointMap
+ } else { // DIDComm V1, default is generic endpoint as string URI
rawService[jsonldServicePoint] = sepURI
}
diff --git a/pkg/doc/did/doc_test.go b/pkg/doc/did/doc_test.go
index b6e5277b6..2a30f0127 100644
--- a/pkg/doc/did/doc_test.go
+++ b/pkg/doc/did/doc_test.go
@@ -265,6 +265,19 @@ func TestValid(t *testing.T) {
recipientKeysRelativeURL: map[string]bool{"did:example:123456789abcdefghi#key2": false},
routingKeysRelativeURL: map[string]bool{"did:example:123456789abcdefghi#key2": false},
},
+ {
+ ID: "did:example:123456789abcdefghi#DIDCommMessaging",
+ Type: "DIDCommMessaging",
+ Priority: 0,
+ RecipientKeys: []string{"did:example:123456789abcdefghi#key2"},
+ ServiceEndpoint: model.NewDIDCommV2Endpoint([]model.DIDCommV2Endpoint{{
+ URI: "https://agent.example.com/",
+ Accept: []string{"didcomm/v2"},
+ RoutingKeys: []string{"did:example:123456789abcdefghi#key2"},
+ }}),
+ Properties: map[string]interface{}{},
+ recipientKeysRelativeURL: map[string]bool{"did:example:123456789abcdefghi#key2": false},
+ },
}
require.EqualValues(t, eServices, doc.Service)
}
diff --git a/pkg/doc/did/testdata/valid_doc.jsonld b/pkg/doc/did/testdata/valid_doc.jsonld
index 5c7075777..26ca510b0 100644
--- a/pkg/doc/did/testdata/valid_doc.jsonld
+++ b/pkg/doc/did/testdata/valid_doc.jsonld
@@ -41,6 +41,13 @@
"priority" : 0,
"recipientKeys" : ["did:example:123456789abcdefghi#key2"],
"routingKeys" : ["did:example:123456789abcdefghi#key2"]
+ },
+ {
+ "id": "did:example:123456789abcdefghi#DIDCommMessaging",
+ "type": "DIDCommMessaging",
+ "serviceEndpoint": [{"uri":"https://agent.example.com/", "accept":["didcomm/v2"], "routingKeys" : ["did:example:123456789abcdefghi#key2"]}],
+ "priority" : 0,
+ "recipientKeys" : ["did:example:123456789abcdefghi#key2"]
}
],
"created": "2002-10-10T17:00:00Z"
From 1135b419c644dfdbc8f07d19fecd18ed8302d27f Mon Sep 17 00:00:00 2001
From: Firas Qutishat
Date: Thu, 2 Jun 2022 23:04:13 +0300
Subject: [PATCH 40/54] chore: add is did comm v2 method to service endpoint
(#3251)
Signed-off-by: Firas Qutishat
---
pkg/common/model/endpoint.go | 6 ++++++
pkg/doc/did/doc.go | 8 ++------
2 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/pkg/common/model/endpoint.go b/pkg/common/model/endpoint.go
index 8a074f703..389c308c7 100644
--- a/pkg/common/model/endpoint.go
+++ b/pkg/common/model/endpoint.go
@@ -17,6 +17,7 @@ type ServiceEndpoint interface {
URI() (string, error)
Accept() ([]string, error)
RoutingKeys() ([]string, error)
+ IsDIDCommV2() bool
}
// Endpoint contains endpoint specific content. Content of ServiceEndpoint api above will be used by priority:
@@ -115,6 +116,11 @@ func (s *Endpoint) RoutingKeys() ([]string, error) {
return nil, fmt.Errorf("endpoint RoutingKeys not found")
}
+// IsDIDCommV2 return is did comm v2 endpoint.
+func (s *Endpoint) IsDIDCommV2() bool {
+ return len(s.rawDIDCommV2) > 0
+}
+
// MarshalJSON marshals the content of Endpoint into a valid JSON []byte. Order of data is:
// 1. DIDCommV2 format if found
// 2. DIDCommV1 format if found
diff --git a/pkg/doc/did/doc.go b/pkg/doc/did/doc.go
index f07545306..f9fd784a0 100644
--- a/pkg/doc/did/doc.go
+++ b/pkg/doc/did/doc.go
@@ -60,10 +60,6 @@ const (
jsonldPublicKeyHex = "publicKeyHex"
jsonldPublicKeyPem = "publicKeyPem"
jsonldPublicKeyjwk = "publicKeyJwk"
-
- // service type added here (to avoid cyclic dependency with vdrapi):
- // didCommV2ServiceType is the DID Communications V2 service type.
- didCommV2ServiceType = "DIDCommMessaging"
)
var (
@@ -1344,7 +1340,7 @@ 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].Type == didCommV2ServiceType {
+ if services[i].ServiceEndpoint.IsDIDCommV2() {
services[i].ServiceEndpoint = model.NewDIDCommV2Endpoint([]model.DIDCommV2Endpoint{
{URI: sepURI, Accept: sepAccept, RoutingKeys: sepRoutingKeys},
})
@@ -1368,7 +1364,7 @@ func populateRawServices(services []Service, didID, baseURI string) []map[string
rawService[jsonldType] = services[i].Type
- if services[i].Type == didCommV2ServiceType { // DIDComm V2
+ if services[i].ServiceEndpoint.IsDIDCommV2() { // DIDComm V2
serviceEndpointMap := []map[string]interface{}{{"uri": sepURI}}
if len(sepAccept) > 0 {
serviceEndpointMap[0]["accept"] = sepAccept
From 5b6aec9c0c0080be41a720c09e740d8c033b3ba8 Mon Sep 17 00:00:00 2001
From: Derek Trider
Date: Fri, 3 Jun 2022 11:29:32 -0400
Subject: [PATCH 41/54] feat: Full EDV provider support for AND+OR multiple tag
queries (#3252)
The EDV storage provider can now do full AND+OR tag querying. The SetStoreConfig method no longer calls the "add index" endpoint as it won't be added to the spec (indexing will be automatically by the EDV server).
Also updated storage interface documentation for the Query method to accommodate the new functionality.
Signed-off-by: Derek Trider
---
component/storage/edv/models.go | 6 -
component/storage/edv/restclient.go | 44 +---
component/storage/edv/restprovider.go | 174 +++++++++-----
component/storage/edv/restprovider_test.go | 250 ++++++++++++---------
scripts/start_edv_test_docker_images.sh | 2 +-
spi/storage/storage.go | 13 +-
6 files changed, 271 insertions(+), 218 deletions(-)
diff --git a/component/storage/edv/models.go b/component/storage/edv/models.go
index ae164fefb..dfc680652 100644
--- a/component/storage/edv/models.go
+++ b/component/storage/edv/models.go
@@ -79,9 +79,3 @@ type vaultOperation struct {
DocumentID string `json:"id,omitempty"` // Only used if Operation=delete
EncryptedDocument json.RawMessage `json:"document,omitempty"` // Only used if Operation=upsert
}
-
-// indexOperation represents an operation to add, update or remove indexes.
-type indexOperation struct {
- Operation string `json:"operation"`
- AttributeNames []string `json:"attributeNames"`
-}
diff --git a/component/storage/edv/restclient.go b/component/storage/edv/restclient.go
index f678e294d..e12f68c31 100644
--- a/component/storage/edv/restclient.go
+++ b/component/storage/edv/restclient.go
@@ -98,20 +98,8 @@ func (c *restClient) readDocument(vaultID, docID string) ([]byte, error) {
// then it acts as a wildcard, where any tag value for the associated tag name will match.
// If query.ReturnFullDocuments is false, then only the document locations will be returned via the first return value.
// If query.ReturnFullDocuments is true, then the full documents will be returned via the second return value.
-func (c *restClient) query(vaultID string, tags []spi.Tag,
- returnFullDocuments bool) ([]string, []encryptedDocument, error) {
- subfilter := make(map[string]string, len(tags))
-
- for _, tag := range tags {
- subfilter[tag.Name] = tag.Value
- }
-
- queryToSend := query{
- Equals: []map[string]string{subfilter},
- ReturnFullDocuments: returnFullDocuments,
- }
-
- jsonToSend, err := json.Marshal(queryToSend)
+func (c *restClient) query(vaultID string, edvQuery query) ([]string, []encryptedDocument, error) {
+ jsonToSend, err := json.Marshal(edvQuery)
if err != nil {
return nil, nil, err
}
@@ -124,7 +112,7 @@ func (c *restClient) query(vaultID string, tags []spi.Tag,
}
if statusCode == http.StatusOK {
- if returnFullDocuments {
+ if edvQuery.ReturnFullDocuments {
var documents []encryptedDocument
err = json.Unmarshal(respBytes, &documents)
@@ -186,32 +174,6 @@ func (c *restClient) deleteDocument(vaultID, docID string) error {
return fmt.Errorf(failResponseFromEDVServer, statusCode, respBytes)
}
-func (c *restClient) addIndex(vaultID string, attributeNames []string) error {
- addIndexOperation := indexOperation{
- Operation: "add",
- AttributeNames: attributeNames,
- }
-
- jsonToSend, err := json.Marshal(addIndexOperation)
- if err != nil {
- return fmt.Errorf("failed to marshal index operation: %w", err)
- }
-
- endpoint := fmt.Sprintf("%s/%s/index", c.edvServerURL, url.PathEscape(vaultID))
-
- statusCode, _, respBytes, err := c.sendHTTPRequest(http.MethodPost, endpoint, jsonToSend, c.headersFunc)
- if err != nil {
- return fmt.Errorf("send HTTP request: %w", err)
- }
-
- if statusCode == http.StatusOK {
- return nil
- }
-
- return fmt.Errorf("the EDV server returned status code %d along with the following message: %s",
- statusCode, respBytes)
-}
-
func (c *restClient) sendHTTPRequest(method, endpoint string, body []byte,
addHeadersFunc addHeaders) (int, http.Header, []byte, error) {
var req *http.Request
diff --git a/component/storage/edv/restprovider.go b/component/storage/edv/restprovider.go
index 5e6028175..0bf07a8bf 100644
--- a/component/storage/edv/restprovider.go
+++ b/component/storage/edv/restprovider.go
@@ -29,7 +29,8 @@ const (
var (
errEmptyKey = errors.New("key cannot be empty")
errInvalidQueryExpressionFormat = errors.New("invalid expression format. " +
- "it must be in the following format: Criterion1&&Criterion2&&...CriterionN")
+ "it must be in the following format: " +
+ "[Criterion1][Operator][Criterion2][Operator]...[CriterionN] (without square brackets)")
)
// RESTProviderOption allows for configuration of a RESTProvider.
@@ -139,10 +140,10 @@ func (r *RESTProvider) OpenStore(name string) (spi.Store, error) {
return openStore, nil
}
-// SetStoreConfig asks the EDV server to add indexes for the tag names specified config.
-// Currently, it is only capable of adding indexes to whatever indexes already exist. No existing indexes will get
-// removed.
-// TODO (#3236): Make this method work in the manner specified by the interface docs.
+// SetStoreConfig isn't needed for EDV storage, since indexes are managed by the server automatically based on the
+// tags used in values. This method simply stores the configuration in memory so that it can be retrieved later
+// via the GetStoreConfig method, which allows it to be more consistent with how other store implementations work.
+// TODO (#2492) Store store config in persistent EDV storage for true consistency with other store implementations.
func (r *RESTProvider) SetStoreConfig(name string, config spi.StoreConfiguration) error {
for _, tagName := range config.TagNames {
if strings.Contains(tagName, ":") {
@@ -152,17 +153,26 @@ func (r *RESTProvider) SetStoreConfig(name string, config spi.StoreConfiguration
name = strings.ToLower(name)
- _, ok := r.openStores[name]
+ openStore, ok := r.openStores[name]
if !ok {
return spi.ErrStoreNotFound
}
- return r.restClient.addIndex(r.vaultID, config.TagNames)
+ openStore.config = config
+
+ return nil
}
-// GetStoreConfig is not implemented. See #3236.
-func (r *RESTProvider) GetStoreConfig(string) (spi.StoreConfiguration, error) {
- return spi.StoreConfiguration{}, errors.New("not implemented")
+// GetStoreConfig returns the store configuration currently stored in memory.
+func (r *RESTProvider) GetStoreConfig(name string) (spi.StoreConfiguration, error) {
+ name = strings.ToLower(name)
+
+ openStore, ok := r.openStores[name]
+ if !ok {
+ return spi.StoreConfiguration{}, spi.ErrStoreNotFound
+ }
+
+ return openStore.config, nil
}
// GetOpenStores returns all currently open stores.
@@ -203,6 +213,7 @@ type restStore struct {
name string
formatter *EncryptedFormatter
restClient *restClient
+ config spi.StoreConfiguration
returnFullDocumentsOnQuery bool
batchEndpointExtensionEnabled bool
close closer
@@ -322,11 +333,14 @@ func (r *restStore) GetBulk(keys ...string) ([][]byte, error) {
return values, nil
}
-// Expression format: Criterion1&&Criterion2&&...CriterionN.
-// The && characters indicate an AND operator. There must be at least one Criterion.
-// Each Criterion can be in one of either two formats: Either "TagName" or "TagName:TagValue" (both without quotes).
+// Expression format: [Criterion1][Operator][Criterion2][Operator]...[CriterionN]. Square brackets are used here for
+// visual clarity. Omit them from the actual expression string.
+// Each Criterion can be in one of either two formats: Either "TagName" or "TagName:TagValue" (without quotes).
// If only using TagName, then the tag value will be treated as a wildcard, so any data tagged with the given TagName
-// will be matched regardless of tag value.
+// will be matched regardless of tag value. There must be at least one Criterion in the expression.
+// Each operator must be either "&&" or "||" (without quotes). "&&" indicates an AND operator while "||"
+// indicates an OR operator. For AND operations, tag names must be unique. e.g. TagName1:TagValue1&&TagName1:TagValue2
+// will not work - the second criterion will overwrite the first. The order of operations are ANDs followed by ORs.
// Note that EDV doesn't support sorting or pagination.
// spi.WithPageSize will simply be ignored since it only relates to performance and not the actual end result.
// spi.WithInitialPageNum and spi.WithSortOrder will result in an error being returned since those options do
@@ -337,17 +351,12 @@ func (r *restStore) Query(expression string, options ...spi.QueryOption) (spi.It
return nil, err
}
- parsedTags, err := parseQueryExpression(expression)
- if err != nil {
- return nil, fmt.Errorf("failed to parse query expression: %w", err)
- }
-
- tags, err := r.formatter.formatTags(r.name, parsedTags)
+ edvQuery, err := r.generateEDVQuery(expression)
if err != nil {
- return nil, fmt.Errorf("failed to format tags for querying: %w", err)
+ return nil, err
}
- return r.query(tags)
+ return r.query(edvQuery)
}
func (r *restStore) Delete(key string) error {
@@ -581,8 +590,12 @@ func (r *restStore) getFullDocumentViaKeyTagQuery(key string) ([]byte, error) {
return nil, fmt.Errorf("failed to format key tag: %w", err)
}
- _, matchingDocuments, err := r.restClient.query(r.vaultID,
- []spi.Tag{{Name: formattedKeyTag.Name, Value: formattedKeyTag.Value}}, true)
+ edvQuery := query{
+ Equals: []map[string]string{{formattedKeyTag.Name: formattedKeyTag.Value}},
+ ReturnFullDocuments: true,
+ }
+
+ _, matchingDocuments, err := r.restClient.query(r.vaultID, edvQuery)
if err != nil {
return nil, fmt.Errorf("failure while querying vault: %w", err)
}
@@ -602,8 +615,8 @@ func (r *restStore) getFullDocumentViaKeyTagQuery(key string) ([]byte, error) {
return encryptedDocumentBytes, nil
}
-func (r *restStore) query(attributeTags []spi.Tag) (spi.Iterator, error) {
- documentURLs, documents, err := r.restClient.query(r.vaultID, attributeTags, r.returnFullDocumentsOnQuery)
+func (r *restStore) query(edvQuery query) (spi.Iterator, error) {
+ documentURLs, documents, err := r.restClient.query(r.vaultID, edvQuery)
if err != nil {
return nil, fmt.Errorf("failure while querying vault: %w", err)
}
@@ -1014,8 +1027,12 @@ func (r *restStore) getDocumentIDViaKeyTagQuery(key string) (string, error) {
return "", fmt.Errorf("failed to format key tag: %w", err)
}
- matchingDocumentsURLs, _, err := r.restClient.query(r.vaultID,
- []spi.Tag{{Name: formattedKeyTag.Name, Value: formattedKeyTag.Value}}, false)
+ edvQuery := query{
+ Equals: []map[string]string{{formattedKeyTag.Name: formattedKeyTag.Value}},
+ ReturnFullDocuments: false,
+ }
+
+ matchingDocumentsURLs, _, err := r.restClient.query(r.vaultID, edvQuery)
if err != nil {
return "", fmt.Errorf("failure while querying EDV server: %w", err)
}
@@ -1030,6 +1047,79 @@ func (r *restStore) getDocumentIDViaKeyTagQuery(key string) (string, error) {
return getDocIDFromURL(matchingDocumentsURLs[0]), nil
}
+func (r *restStore) generateEDVQuery(expression string) (query, error) {
+ if expression == "" {
+ return query{}, errInvalidQueryExpressionFormat
+ }
+
+ orCriteria := strings.Split(expression, "||")
+
+ edvQuery := query{
+ Equals: make([]map[string]string, len(orCriteria)),
+ Has: "",
+ ReturnFullDocuments: r.returnFullDocumentsOnQuery,
+ }
+
+ for i, orCriterion := range orCriteria {
+ edvQuerySubfilter, err := r.generateEDVQuerySubfilter(orCriterion)
+ if err != nil {
+ return query{}, err
+ }
+
+ edvQuery.Equals[i] = edvQuerySubfilter
+ }
+
+ // See comments above the generateEDVQuerySubfilter method for an explanation of the code below.
+ if len(edvQuery.Equals) == 1 && len(edvQuery.Equals[0]) == 1 {
+ for formattedTagName, formattedTagValue := range edvQuery.Equals[0] {
+ if formattedTagValue == "" {
+ edvQuery.Equals = nil
+ edvQuery.Has = formattedTagName
+ }
+ }
+ }
+
+ return edvQuery, nil
+}
+
+// As of writing, the EDV spec does not have an official way to do an attribute name (tag name/"has") only query when
+// doing a multiple attribute query. I have an open PR in the spec to address this. In the meantime, the TrustBloc EDV
+// implementation interprets a blank attribute value as behaving like an attribute name only (tag name/"has") query,
+// so that's what this method does.
+// In the case of the overall query being just a single attribute name only, the method that calls this will ensure that
+// a "has" query is used in order to ensure maximum compatibility.
+func (r *restStore) generateEDVQuerySubfilter(expression string) (map[string]string, error) {
+ subfilter := make(map[string]string)
+
+ andCriteria := strings.Split(expression, "&&")
+
+ for _, andCriterion := range andCriteria {
+ criterionSplitByTagNameAndValue := strings.Split(andCriterion, ":")
+
+ switch len(criterionSplitByTagNameAndValue) {
+ case criterionTagNameOnlyLength:
+ formattedTag, err := r.formatter.formatTag(r.name, spi.Tag{Name: criterionSplitByTagNameAndValue[0]})
+ if err != nil {
+ return nil, fmt.Errorf("failed to format tag for querying: %w", err)
+ }
+
+ subfilter[formattedTag.Name] = ""
+ case criterionTagNameAndValueLength:
+ formattedTag, err := r.formatter.formatTag(r.name,
+ spi.Tag{Name: criterionSplitByTagNameAndValue[0], Value: criterionSplitByTagNameAndValue[1]})
+ if err != nil {
+ return nil, fmt.Errorf("failed to format tag for querying: %w", err)
+ }
+
+ subfilter[formattedTag.Name] = formattedTag.Value
+ default:
+ return nil, errInvalidQueryExpressionFormat
+ }
+ }
+
+ return subfilter, nil
+}
+
type restIterator struct {
vaultID string
restClient *restClient
@@ -1164,34 +1254,6 @@ func checkForUnsupportedQueryOptions(options []spi.QueryOption) error {
return nil
}
-func parseQueryExpression(expression string) ([]spi.Tag, error) {
- if expression == "" {
- return nil, errInvalidQueryExpressionFormat
- }
-
- criteria := strings.Split(expression, "&&")
-
- parsedTags := make([]spi.Tag, len(criteria))
-
- for i, criterion := range criteria {
- criterionSplitByTagNameAndValue := strings.Split(criterion, ":")
-
- switch len(criterionSplitByTagNameAndValue) {
- case criterionTagNameOnlyLength:
- parsedTags[i] = spi.Tag{Name: criterionSplitByTagNameAndValue[0]}
- case criterionTagNameAndValueLength:
- parsedTags[i] = spi.Tag{
- Name: criterionSplitByTagNameAndValue[0],
- Value: criterionSplitByTagNameAndValue[1],
- }
- default:
- return nil, errInvalidQueryExpressionFormat
- }
- }
-
- return parsedTags, nil
-}
-
func getDocIDFromURL(docURL string) string {
splitBySlashes := strings.Split(docURL, `/`)
docIDToRetrieve := splitBySlashes[len(splitBySlashes)-1]
diff --git a/component/storage/edv/restprovider_test.go b/component/storage/edv/restprovider_test.go
index dafe59c23..0afd322a1 100644
--- a/component/storage/edv/restprovider_test.go
+++ b/component/storage/edv/restprovider_test.go
@@ -119,38 +119,6 @@ func runCommonTests(t *testing.T, provider spi.Provider, commonTestOptions []sto
testQueryWithMultipleTags(t, provider)
}
-func TestRESTProvider_SetStoreConfig(t *testing.T) {
- t.Run("Unsupported protocol scheme", func(t *testing.T) {
- edvRESTProvider := edv.NewRESTProvider("BadURL", "VaultID",
- createValidEncryptedFormatter(t))
-
- _, err := edvRESTProvider.OpenStore("TestStore")
- require.NoError(t, err)
-
- err = edvRESTProvider.SetStoreConfig("TestStore", spi.StoreConfiguration{})
- require.EqualError(t, err, "send HTTP request: failed to send request: "+
- `Post "BadURL/VaultID/index": unsupported protocol scheme ""`)
- })
- t.Run("Vault does not exist", func(t *testing.T) {
- edvRESTProvider := edv.NewRESTProvider(testServerURL, "VaultID",
- createValidEncryptedFormatter(t))
-
- _, err := edvRESTProvider.OpenStore("TestStore")
- require.NoError(t, err)
-
- err = edvRESTProvider.SetStoreConfig("TestStore", spi.StoreConfiguration{})
- require.EqualError(t, err, "the EDV server returned status code 400 along with the following "+
- "message: Failed to add indexes to data vault VaultID: specified vault does not exist.")
- })
-}
-
-func TestRESTProvider_GetStoreConfig(t *testing.T) {
- edvRESTProvider := createEDVRESTProvider(t, createValidEncryptedFormatter(t))
-
- _, err := edvRESTProvider.GetStoreConfig("StoreName")
- require.EqualError(t, err, "not implemented")
-}
-
func TestRESTStore_Put(t *testing.T) {
t.Run("Fail to generate encrypted document ID and encrypted document bytes "+
"for vault operation (batch extension enabled)", func(t *testing.T) {
@@ -346,7 +314,7 @@ func TestRESTStore_Query(t *testing.T) {
require.NoError(t, err)
iterator, err := store.Query("TagName:TagValue")
- require.EqualError(t, err, `failed to format tags for querying: failed to format tag: `+
+ require.EqualError(t, err, `failed to format tag for querying: `+
`failed to compute MAC for tag name "TagName": bad key handle format`)
require.Nil(t, iterator)
})
@@ -590,7 +558,7 @@ func TestRESTStore_Batch(t *testing.T) {
})
}
-func testQueryWithMultipleTags(t *testing.T, provider spi.Provider) {
+func testQueryWithMultipleTags(t *testing.T, provider spi.Provider) { //nolint:gocyclo // test file
t.Helper()
defer func() {
@@ -610,106 +578,154 @@ func testQueryWithMultipleTags(t *testing.T, provider spi.Provider) {
putData(t, store, keysToPut, valuesToPut, tagsToPut)
- t.Run("Both pairs are tag names + values - 3 values found", func(t *testing.T) {
- queryExpressionsToTest := []string{
- "Breed:GoldenRetriever&&NumLegs:4&&EarType:Floppy",
- "NumLegs:4&&EarType:Floppy&&Breed:GoldenRetriever", // Should be equivalent to the above expression
- }
+ t.Run("AND queries", func(t *testing.T) {
+ t.Run("Two tag name + value pairs - 2 values found", func(t *testing.T) {
+ queryExpressionsToTest := []string{
+ "Breed:GoldenRetriever&&Personality:Calm",
+ "Personality:Calm&&Breed:GoldenRetriever", // Should be equivalent to the above expression
+ }
- expectedKeys := []string{keysToPut[0], keysToPut[3], keysToPut[4]}
- expectedValues := [][]byte{valuesToPut[0], valuesToPut[3], valuesToPut[4]}
- expectedTags := [][]spi.Tag{tagsToPut[0], tagsToPut[3], tagsToPut[4]}
- expectedTotalItemsCount := 3
+ expectedKeys, expectedValues, expectedTags := getExpectedData([]int{3, 4})
- for _, queryExpressionToTest := range queryExpressionsToTest {
- iterator, err := store.Query(queryExpressionToTest)
- require.NoError(t, err)
+ for _, queryExpressionToTest := range queryExpressionsToTest {
+ iterator, err := store.Query(queryExpressionToTest)
+ require.NoError(t, err)
- verifyExpectedIterator(t, iterator, expectedKeys, expectedValues, expectedTags, expectedTotalItemsCount)
- }
- })
- t.Run("Both pairs are tag names + values - 2 values found", func(t *testing.T) {
- queryExpressionsToTest := []string{
- "Breed:GoldenRetriever&&Personality:Calm",
- "Personality:Calm&&Breed:GoldenRetriever", // Should be equivalent to the above expression
- }
+ verifyExpectedIterator(t, iterator, expectedKeys, expectedValues, expectedTags, len(expectedKeys))
+ }
+ })
+ t.Run("Two tag name + value pairs - 1 value found", func(t *testing.T) {
+ queryExpressionsToTest := []string{
+ "Personality:Shy&&EarType:Pointy",
+ "EarType:Pointy&&Personality:Shy", // Should be equivalent to the above expression
+ }
- expectedKeys := []string{keysToPut[3], keysToPut[4]}
- expectedValues := [][]byte{valuesToPut[3], valuesToPut[4]}
- expectedTags := [][]spi.Tag{tagsToPut[3], tagsToPut[4]}
- expectedTotalItemsCount := 2
+ expectedKeys, expectedValues, expectedTags := getExpectedData([]int{1})
- for _, queryExpressionToTest := range queryExpressionsToTest {
- iterator, err := store.Query(queryExpressionToTest)
- require.NoError(t, err)
+ for _, queryExpressionToTest := range queryExpressionsToTest {
+ iterator, err := store.Query(queryExpressionToTest)
+ require.NoError(t, err)
- verifyExpectedIterator(t, iterator, expectedKeys, expectedValues, expectedTags, expectedTotalItemsCount)
- }
- })
- t.Run("Both pairs are tag names + values - 1 value found", func(t *testing.T) {
- queryExpressionsToTest := []string{
- "Personality:Shy&&EarType:Pointy",
- "EarType:Pointy&&Personality:Shy", // Should be equivalent to the above expression
- }
+ verifyExpectedIterator(t, iterator, expectedKeys, expectedValues, expectedTags, len(expectedKeys))
+ }
+ })
+ t.Run("Two tag name + value pairs - 0 values found", func(t *testing.T) {
+ queryExpressionsToTest := []string{
+ "Personality:Crazy&&EarType:Pointy",
+ "EarType:Pointy&&Personality:Crazy", // Should be equivalent to the above expression
+ }
- expectedKeys := []string{keysToPut[1]}
- expectedValues := [][]byte{valuesToPut[1]}
- expectedTags := [][]spi.Tag{tagsToPut[1]}
- expectedTotalItemsCount := 1
+ for _, queryExpressionToTest := range queryExpressionsToTest {
+ iterator, err := store.Query(queryExpressionToTest)
+ require.NoError(t, err)
- for _, queryExpressionToTest := range queryExpressionsToTest {
- iterator, err := store.Query(queryExpressionToTest)
- require.NoError(t, err)
+ verifyExpectedIterator(t, iterator, nil, nil, nil, 0)
+ }
+ })
+ t.Run("One tag name + value pair and an additional tag name - 1 value found", func(t *testing.T) {
+ queryExpressionsToTest := []string{
+ "EarType:Pointy&&Nickname",
+ "Nickname&&EarType:Pointy", // Should be equivalent to the above expression
+ }
- verifyExpectedIterator(t, iterator, expectedKeys, expectedValues, expectedTags, expectedTotalItemsCount)
- }
- })
- t.Run("Both pairs are tag names + values - 0 values found", func(t *testing.T) {
- queryExpressionsToTest := []string{
- "Personality:Crazy&&EarType:Pointy",
- "EarType:Pointy&&Personality:Crazy", // Should be equivalent to the above expression
- }
+ expectedKeys, expectedValues, expectedTags := getExpectedData([]int{2})
- expectedTotalItemsCount := 0
+ for _, queryExpressionToTest := range queryExpressionsToTest {
+ iterator, err := store.Query(queryExpressionToTest)
+ require.NoError(t, err)
- for _, queryExpressionToTest := range queryExpressionsToTest {
- iterator, err := store.Query(queryExpressionToTest)
- require.NoError(t, err)
+ verifyExpectedIterator(t, iterator, expectedKeys, expectedValues, expectedTags, len(expectedKeys))
+ }
+ })
+ t.Run("One tag name + value pair and an additional tag name - 0 values found", func(t *testing.T) {
+ queryExpressionsToTest := []string{
+ "EarType:Pointy&&CoatType",
+ "CoatType&&EarType:Pointy", // Should be equivalent to the above expression
+ }
- verifyExpectedIterator(t, iterator, nil, nil, nil, expectedTotalItemsCount)
- }
+ for _, queryExpressionToTest := range queryExpressionsToTest {
+ iterator, err := store.Query(queryExpressionToTest)
+ require.NoError(t, err)
+
+ verifyExpectedIterator(t, iterator, nil, nil, nil, 0)
+ }
+ })
+ t.Run("Three tag name + values pairs - 3 values found", func(t *testing.T) {
+ queryExpressionsToTest := []string{
+ "Breed:GoldenRetriever&&NumLegs:4&&EarType:Floppy",
+ "NumLegs:4&&EarType:Floppy&&Breed:GoldenRetriever", // Should be equivalent to the above expression
+ }
+
+ expectedKeys, expectedValues, expectedTags := getExpectedData([]int{0, 3, 4})
+
+ for _, queryExpressionToTest := range queryExpressionsToTest {
+ iterator, err := store.Query(queryExpressionToTest)
+ require.NoError(t, err)
+
+ verifyExpectedIterator(t, iterator, expectedKeys, expectedValues, expectedTags, len(expectedKeys))
+ }
+ })
})
- t.Run("First pair is a tag name + value, second is a tag name only - 1 value found", func(t *testing.T) {
- queryExpressionsToTest := []string{
- "EarType:Pointy&&Nickname",
- "Nickname&&EarType:Pointy", // Should be equivalent to the above expression
- }
+ t.Run("OR queries", func(t *testing.T) {
+ t.Run("Two tag name + value pairs - 2 values found", func(t *testing.T) {
+ queryExpressionsToTest := []string{
+ "Breed:GoldenRetriever||Nickname:Fluffball",
+ "Nickname:Fluffball||Breed:GoldenRetriever", // Should be equivalent to the above expression
+ }
- expectedKeys := []string{keysToPut[2]}
- expectedValues := [][]byte{valuesToPut[2]}
- expectedTags := [][]spi.Tag{tagsToPut[2]}
- expectedTotalItemsCount := 1
+ expectedKeys, expectedValues, expectedTags := getExpectedData([]int{0, 2, 3, 4})
- for _, queryExpressionToTest := range queryExpressionsToTest {
- iterator, err := store.Query(queryExpressionToTest)
- require.NoError(t, err)
+ for _, queryExpressionToTest := range queryExpressionsToTest {
+ iterator, err := store.Query(queryExpressionToTest)
+ require.NoError(t, err)
- verifyExpectedIterator(t, iterator, expectedKeys, expectedValues, expectedTags, expectedTotalItemsCount)
- }
+ verifyExpectedIterator(t, iterator, expectedKeys, expectedValues, expectedTags, len(expectedKeys))
+ }
+ })
+ t.Run("One tag name + value pair and an additional tag name - 3 values found", func(t *testing.T) {
+ queryExpressionsToTest := []string{
+ "Nickname||Breed:Schweenie",
+ "Breed:Schweenie||Nickname", // Should be equivalent to the above expression
+ }
+
+ expectedKeys, expectedValues, expectedTags := getExpectedData([]int{0, 1, 2})
+
+ for _, queryExpressionToTest := range queryExpressionsToTest {
+ iterator, err := store.Query(queryExpressionToTest)
+ require.NoError(t, err)
+
+ verifyExpectedIterator(t, iterator, expectedKeys, expectedValues, expectedTags, len(expectedKeys))
+ }
+ })
+ t.Run("Three tag name + values pairs - 4 values found", func(t *testing.T) {
+ queryExpressionsToTest := []string{
+ "Breed:GoldenRetriever||Nickname:Fluffball||Age:1",
+ "Age:1||Nickname:Fluffball||Breed:GoldenRetriever", // Should be equivalent to the above expression
+ }
+
+ expectedKeys, expectedValues, expectedTags := getExpectedData([]int{0, 1, 2, 3, 4})
+
+ for _, queryExpressionToTest := range queryExpressionsToTest {
+ iterator, err := store.Query(queryExpressionToTest)
+ require.NoError(t, err)
+
+ verifyExpectedIterator(t, iterator, expectedKeys, expectedValues, expectedTags, len(expectedKeys))
+ }
+ })
})
- t.Run("First pair is a tag name + value, second is a tag name only - 0 values found", func(t *testing.T) {
+ t.Run("AND+OR combined query", func(t *testing.T) {
queryExpressionsToTest := []string{
- "EarType:Pointy&&CoatType",
- "CoatType&&EarType:Pointy", // Should be equivalent to the above expression
+ "Breed:GoldenRetriever&&Personality:Calm||Nickname:Fluffball",
+ "Nickname:Fluffball||Breed:GoldenRetriever&&Personality:Calm", // Should be equivalent to the above expression
}
- expectedTotalItemsCount := 0
+ expectedKeys, expectedValues, expectedTags := getExpectedData([]int{2, 3, 4})
for _, queryExpressionToTest := range queryExpressionsToTest {
iterator, err := store.Query(queryExpressionToTest)
require.NoError(t, err)
- verifyExpectedIterator(t, iterator, nil, nil, nil, expectedTotalItemsCount)
+ verifyExpectedIterator(t, iterator, expectedKeys, expectedValues, expectedTags, len(expectedKeys))
}
})
}
@@ -773,6 +789,22 @@ func getTestData() (testKeys []string, testValues [][]byte, testTags [][]spi.Tag
return testKeys, testValues, testTags
}
+func getExpectedData(expectedIndexes []int) (expectedKeys []string, expectedValues [][]byte, expectedTags [][]spi.Tag) {
+ keys, values, tags := getTestData()
+
+ expectedKeys = make([]string, len(expectedIndexes))
+ expectedValues = make([][]byte, len(expectedIndexes))
+ expectedTags = make([][]spi.Tag, len(expectedIndexes))
+
+ for i, expectedIndex := range expectedIndexes {
+ expectedKeys[i] = keys[expectedIndex]
+ expectedValues[i] = values[expectedIndex]
+ expectedTags[i] = tags[expectedIndex]
+ }
+
+ return expectedKeys, expectedValues, expectedTags
+}
+
func putData(t *testing.T, store spi.Store, keys []string, values [][]byte, tags [][]spi.Tag) {
t.Helper()
diff --git a/scripts/start_edv_test_docker_images.sh b/scripts/start_edv_test_docker_images.sh
index 18cd7abe4..55a7bfdc1 100755
--- a/scripts/start_edv_test_docker_images.sh
+++ b/scripts/start_edv_test_docker_images.sh
@@ -47,4 +47,4 @@ PWD=$(pwd)
docker run -p 27017:27017 -d --network AriesTestNetwork --name AriesMongoDBStorageTest mongo:4.0.0 >/dev/null
-docker run -p 8071:8071 -d --network AriesTestNetwork --name AriesEDVStorageTest ghcr.io/trustbloc-cicd/edv:0.1.9-snapshot-fb17917 start --host-url 0.0.0.0:8071 --database-prefix edv_db_ --database-type mongodb --database-url mongodb://AriesMongoDBStorageTest:27017 --with-extensions Batch >/dev/null
+docker run -p 8071:8071 -d --network AriesTestNetwork --name AriesEDVStorageTest ghcr.io/trustbloc-cicd/edv:0.1.9-snapshot-894c500 start --host-url 0.0.0.0:8071 --database-prefix edv_db_ --database-type mongodb --database-url mongodb://AriesMongoDBStorageTest:27017 --with-extensions Batch --log-level=debug >/dev/null
diff --git a/spi/storage/storage.go b/spi/storage/storage.go
index 8769b9230..bfb9e8108 100644
--- a/spi/storage/storage.go
+++ b/spi/storage/storage.go
@@ -205,13 +205,16 @@ type Store interface {
// As of writing, aries-framework-go code does not use this, but it may be useful for custom solutions.
GetBulk(keys ...string) ([][]byte, error)
- // Query returns all data that satisfies the expression. Expression format: TagName:TagValue.
+ // Query returns all data that satisfies the expression. Basic expression format: TagName:TagValue.
// If TagValue is not provided, then all data associated with the TagName will be returned, regardless of their
// tag values.
- // At a minimum, a store implementation must be able to support querying with a single TagName:TagValue pair, but a
- // store implementation may also support querying for multiple TagName:TagValue pairs by separating them with an
- // && to specify an AND operation or a || to specify an OR operation. For example, a query for
- // TagName1:TagValue1&&TagName2:TagValue2 will return only data that has been tagged with both pairs.
+ // At a minimum, a store implementation must be able to support querying with a single basic expression, but a
+ // store implementation may also support a more advanced expression format.
+ // Advanced expression format: [Criterion1][Operator][Criterion2][Operator]...[CriterionN]. Square brackets are
+ // used here for visual clarity. Omit them from the actual expression string.
+ // Each Criterion follows the rules for the basic expression format described above.
+ // Each operator must be either "&&" or "||" (without quotes). "&&" indicates an AND operator while "||"
+ // indicates an OR operator. The order of operations are ANDs followed by ORs.
// This method also supports a number of QueryOptions. If none are provided, then defaults will be used.
// If your store contains a large amount of data, then it's recommended calling Provider.SetStoreConfig at some
// point before calling this method in order to create indexes which will speed up queries.
From 53422361c38cdcaa8e165787b4caa1fd14000d15 Mon Sep 17 00:00:00 2001
From: Firas Qutishat
Date: Mon, 6 Jun 2022 15:45:20 +0300
Subject: [PATCH 42/54] chore: add new method to return endpoint type (#3254)
Signed-off-by: Firas Qutishat
---
pkg/common/model/endpoint.go | 28 ++++++++++++++++++++++++----
pkg/common/model/endpoint_test.go | 3 +++
pkg/doc/did/doc.go | 4 ++--
3 files changed, 29 insertions(+), 6 deletions(-)
diff --git a/pkg/common/model/endpoint.go b/pkg/common/model/endpoint.go
index 389c308c7..af0bc028b 100644
--- a/pkg/common/model/endpoint.go
+++ b/pkg/common/model/endpoint.go
@@ -12,12 +12,24 @@ import (
"net/url"
)
+// EndpointType endpoint type.
+type EndpointType int
+
+const (
+ // DIDCommV1 type.
+ DIDCommV1 EndpointType = iota
+ // DIDCommV2 type.
+ DIDCommV2
+ // Generic type.
+ Generic
+)
+
// ServiceEndpoint api for fetching ServiceEndpoint content based off of a DIDComm V1, V2 or DIDCore format.
type ServiceEndpoint interface {
URI() (string, error)
Accept() ([]string, error)
RoutingKeys() ([]string, error)
- IsDIDCommV2() bool
+ Type() EndpointType
}
// Endpoint contains endpoint specific content. Content of ServiceEndpoint api above will be used by priority:
@@ -116,9 +128,17 @@ func (s *Endpoint) RoutingKeys() ([]string, error) {
return nil, fmt.Errorf("endpoint RoutingKeys not found")
}
-// IsDIDCommV2 return is did comm v2 endpoint.
-func (s *Endpoint) IsDIDCommV2() bool {
- return len(s.rawDIDCommV2) > 0
+// Type return endpoint type.
+func (s *Endpoint) Type() EndpointType {
+ if len(s.rawDIDCommV2) > 0 {
+ return DIDCommV2
+ }
+
+ if s.rawDIDCommV1 != "" {
+ return DIDCommV1
+ }
+
+ return Generic
}
// MarshalJSON marshals the content of Endpoint into a valid JSON []byte. Order of data is:
diff --git a/pkg/common/model/endpoint_test.go b/pkg/common/model/endpoint_test.go
index f48924179..6eb93876f 100644
--- a/pkg/common/model/endpoint_test.go
+++ b/pkg/common/model/endpoint_test.go
@@ -28,6 +28,7 @@ func TestNewEndpoint(t *testing.T) {
ep := NewDIDCommV2Endpoint([]DIDCommV2Endpoint{{uri, accept, routingkeys}})
require.EqualValues(t, didCommV2Endpoint, ep)
+ require.Equal(t, DIDCommV2, ep.Type())
didCommV1Endpoint := Endpoint{
rawDIDCommV1: uri,
@@ -35,6 +36,7 @@ func TestNewEndpoint(t *testing.T) {
ep = NewDIDCommV1Endpoint(uri)
require.EqualValues(t, didCommV1Endpoint, ep)
+ require.Equal(t, DIDCommV1, ep.Type())
didCoreEndpoint := Endpoint{
rawObj: []string{uri, "uri2"},
@@ -42,6 +44,7 @@ func TestNewEndpoint(t *testing.T) {
ep = NewDIDCoreEndpoint([]string{uri, "uri2"})
require.EqualValues(t, didCoreEndpoint, ep)
+ require.Equal(t, Generic, ep.Type())
ep = NewDIDCommV1Endpoint("")
require.EqualValues(t, Endpoint{}, ep)
diff --git a/pkg/doc/did/doc.go b/pkg/doc/did/doc.go
index f9fd784a0..69f7c8cd6 100644
--- a/pkg/doc/did/doc.go
+++ b/pkg/doc/did/doc.go
@@ -1340,7 +1340,7 @@ 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.IsDIDCommV2() {
+ if services[i].ServiceEndpoint.Type() == model.DIDCommV2 {
services[i].ServiceEndpoint = model.NewDIDCommV2Endpoint([]model.DIDCommV2Endpoint{
{URI: sepURI, Accept: sepAccept, RoutingKeys: sepRoutingKeys},
})
@@ -1364,7 +1364,7 @@ func populateRawServices(services []Service, didID, baseURI string) []map[string
rawService[jsonldType] = services[i].Type
- if services[i].ServiceEndpoint.IsDIDCommV2() { // DIDComm V2
+ if services[i].ServiceEndpoint.Type() == model.DIDCommV2 { // DIDComm V2
serviceEndpointMap := []map[string]interface{}{{"uri": sepURI}}
if len(sepAccept) > 0 {
serviceEndpointMap[0]["accept"] = sepAccept
From c826da9691382ccdbf9175aa5c5f831feaade36b Mon Sep 17 00:00:00 2001
From: Derek Trider
Date: Mon, 6 Jun 2022 21:55:08 -0400
Subject: [PATCH 43/54] feat: Update EDV provider version for wallet (#3255)
Signed-off-by: Derek Trider
---
cmd/aries-agent-mobile/go.mod | 33 +++++++++++-----------
cmd/aries-agent-mobile/go.sum | 50 ++++++++++++++++++++++-----------
cmd/aries-agent-rest/go.mod | 29 ++++++++++---------
cmd/aries-agent-rest/go.sum | 53 +++++++++++++++++++++++------------
cmd/aries-js-worker/go.mod | 29 ++++++++++---------
cmd/aries-js-worker/go.sum | 41 +++++++++++++++++++--------
component/storage/edv/go.sum | 2 --
go.mod | 27 +++++++++---------
go.sum | 49 ++++++++++++++++++++++----------
test/bdd/go.mod | 28 +++++++++---------
test/bdd/go.sum | 48 ++++++++++++++++++++-----------
11 files changed, 239 insertions(+), 150 deletions(-)
diff --git a/cmd/aries-agent-mobile/go.mod b/cmd/aries-agent-mobile/go.mod
index a549aa75b..f25defa71 100644
--- a/cmd/aries-agent-mobile/go.mod
+++ b/cmd/aries-agent-mobile/go.mod
@@ -7,13 +7,13 @@ module github.com/hyperledger/aries-framework-go/cmd/aries-agent-mobile
go 1.17
require (
- github.com/google/uuid v1.1.2
- github.com/hyperledger/aries-framework-go v0.1.8-0.20220217153004-1622c70e5767
+ github.com/google/uuid v1.3.0
+ github.com/hyperledger/aries-framework-go v0.1.8-0.20220322085443-50e8f9bd208b
github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220322085443-50e8f9bd208b
- github.com/hyperledger/aries-framework-go/spi v0.0.0-20220322085443-50e8f9bd208b
- github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220322085443-50e8f9bd208b
- github.com/piprate/json-gold v0.4.1-0.20210813112359-33b90c4ca86c
- github.com/stretchr/testify v1.7.0
+ github.com/hyperledger/aries-framework-go/spi v0.0.0-20220606124520-53422361c38c
+ github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220428211718-66cc046674a1
+ github.com/piprate/json-gold v0.4.1
+ github.com/stretchr/testify v1.7.2
nhooyr.io/websocket v1.8.3
)
@@ -29,9 +29,9 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/snappy v0.0.1 // indirect
- github.com/google/tink/go v1.6.1-0.20210519071714-58be99b3c4d0 // indirect
+ github.com/google/tink/go v1.6.1 // indirect
github.com/gorilla/mux v1.7.3 // indirect
- github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220322085443-50e8f9bd208b // indirect
+ github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220606124520-53422361c38c // indirect
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a // indirect
github.com/kawamuray/jsonpath v0.0.0-20201211160320-7483bafabd7e // indirect
github.com/kilic/bls12-381 v0.1.1-0.20210503002446-7b7597926c69 // indirect
@@ -39,14 +39,15 @@ require (
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 // indirect
github.com/minio/sha256-simd v0.1.1 // indirect
github.com/mitchellh/mapstructure v1.1.2 // indirect
- github.com/mr-tron/base58 v1.1.3 // indirect
- github.com/multiformats/go-base32 v0.0.3 // indirect
- github.com/multiformats/go-multibase v0.0.1 // indirect
+ github.com/mr-tron/base58 v1.2.0 // indirect
+ github.com/multiformats/go-base32 v0.0.4 // indirect
+ github.com/multiformats/go-base36 v0.1.0 // indirect
+ github.com/multiformats/go-multibase v0.0.3 // indirect
github.com/multiformats/go-multihash v0.0.13 // indirect
github.com/multiformats/go-varint v0.0.5 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
- github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect
+ github.com/pquerna/cachecontrol v0.1.0 // indirect
github.com/rs/cors v1.7.0 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/square/go-jose/v3 v3.0.0-20200630053402-0a67ce9b0693 // indirect
@@ -58,10 +59,10 @@ require (
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
- golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e // indirect
- golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect
- google.golang.org/protobuf v1.27.1 // indirect
- gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
+ golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect
+ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect
+ google.golang.org/protobuf v1.28.0 // indirect
+ gopkg.in/yaml.v3 v3.0.1 // indirect
)
replace (
diff --git a/cmd/aries-agent-mobile/go.sum b/cmd/aries-agent-mobile/go.sum
index dab7b54f6..40521a2d4 100644
--- a/cmd/aries-agent-mobile/go.sum
+++ b/cmd/aries-agent-mobile/go.sum
@@ -150,10 +150,12 @@ github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hf
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
-github.com/google/tink/go v1.6.1-0.20210519071714-58be99b3c4d0 h1:M1kxKye//XPsRJs+DaWPeDgMWK2zuZHWx/easVWhcVc=
github.com/google/tink/go v1.6.1-0.20210519071714-58be99b3c4d0/go.mod h1:IGW53kTgag+st5yPhKKwJ6u2l+SSp5/v9XF7spovjlY=
-github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
+github.com/google/tink/go v1.6.1 h1:t7JHqO8Ath2w2ig5vjwQYJzhGEZymedQc90lQXUBa4I=
+github.com/google/tink/go v1.6.1/go.mod h1:IGW53kTgag+st5yPhKKwJ6u2l+SSp5/v9XF7spovjlY=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
+github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
@@ -182,12 +184,11 @@ github.com/hashicorp/vault/sdk v0.1.13/go.mod h1:B+hVj7TpuQY1Y/GPbCpffmgd+tSEwvh
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
-github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220322085443-50e8f9bd208b h1:cZ1scj+jdCT6IYAXe/62CckfTXv1wr0vnFLh2biH2qQ=
-github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220322085443-50e8f9bd208b/go.mod h1:eIac5lubCy3tw6D0sTluM5U6Bw3inBwUfjX17o2U7PE=
-github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210820153043-8b6f36d10ab9/go.mod h1:7jEZdg455syX4f+ozLgwhYfIuiEQ/TgdIoOyALMwPG0=
-github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220217153004-1622c70e5767/go.mod h1:HojN6OAh8ZtXBe5X2arcSOe1SLo5Dsjqto8ICjSLQ2g=
-github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220322085443-50e8f9bd208b h1:tq8CYv5vCJBSG2CjWKNt4l1BzZVJUy+GGF4U80fJV8o=
+github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220606124520-53422361c38c h1:8yL/HlgZmfsyXdLJjdE0gBAUjAuW9ZU4I+OiVkil22w=
+github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220606124520-53422361c38c/go.mod h1:JrwivOOQmuXbV1mFWgBGWnfCorOFdfGkpBsYK8dYrfM=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220322085443-50e8f9bd208b/go.mod h1:HojN6OAh8ZtXBe5X2arcSOe1SLo5Dsjqto8ICjSLQ2g=
+github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220428211718-66cc046674a1 h1:vxZ0DlFNLjgxMdBESLZu895AsI1JWL2SJerphwIn8Po=
+github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220428211718-66cc046674a1/go.mod h1:lykx3N+GX+sAWSxO2Ycc4Dz+ynV9b0Fv4NdP+ms4Alc=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
@@ -228,12 +229,17 @@ github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQz
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8=
-github.com/mr-tron/base58 v1.1.3 h1:v+sk57XuaCKGXpWtVBX8YJzO7hMGx4Aajh4TQbdEFdc=
github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
-github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI=
+github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
+github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA=
-github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA=
+github.com/multiformats/go-base32 v0.0.4 h1:+qMh4a2f37b4xTNs6mqitDinryCI+tfO2dRVMN9mjSE=
+github.com/multiformats/go-base32 v0.0.4/go.mod h1:jNLFzjPZtp3aIARHbJRZIaPuspdH0J6q39uUM5pnABM=
+github.com/multiformats/go-base36 v0.1.0 h1:JR6TyF7JjGd3m6FbLU2cOxhC0Li8z8dLNGQ89tUg4F4=
+github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM=
github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs=
+github.com/multiformats/go-multibase v0.0.3 h1:l/B6bJDQjvQ5G52jw4QGSYeOTZoAwIO77RblWplfIqk=
+github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc=
github.com/multiformats/go-multihash v0.0.13 h1:06x+mk/zj1FoMsgNejLpy6QTvJqlSt/BhLEy87zidlc=
github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc=
github.com/multiformats/go-varint v0.0.5 h1:XVZwSo04Cs3j/jS0uAEPpT3JY6DzMcVLLoWOSnCxOjg=
@@ -245,15 +251,17 @@ github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
-github.com/piprate/json-gold v0.4.1-0.20210813112359-33b90c4ca86c h1:F4YQvOA7UTccz06y59KLw4C0iXD28hnKUP9R9zeSe8U=
github.com/piprate/json-gold v0.4.1-0.20210813112359-33b90c4ca86c/go.mod h1:OK1z7UgtBZk06n2cDE2OSq1kffmjFFp5/2yhLLCz9UM=
+github.com/piprate/json-gold v0.4.1 h1:JYbYN36n6YcAYipKy3ttv3X2HDQPeqWqmwta35NPj04=
+github.com/piprate/json-gold v0.4.1/go.mod h1:OK1z7UgtBZk06n2cDE2OSq1kffmjFFp5/2yhLLCz9UM=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
-github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 h1:J9b7z+QKAmPf4YLrFg6oQUotqHQeUNWwkvo7jZp1GLU=
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
+github.com/pquerna/cachecontrol v0.1.0 h1:yJMy84ti9h/+OEWa752kBTKv4XC30OtVVHYv/8cTqKc=
+github.com/pquerna/cachecontrol v0.1.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=
@@ -269,8 +277,9 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s=
+github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
github.com/teserakt-io/golang-ed25519 v0.0.0-20210104091850-3888c087a4c8 h1:RBkacARv7qY5laaXGlF4wFB/tk5rnthhPb8oIBGoagY=
github.com/teserakt-io/golang-ed25519 v0.0.0-20210104091850-3888c087a4c8/go.mod h1:9PdLyPiZIiW3UopXyRnPYyjUXSpiQNHRLu8fOsR3o8M=
github.com/tidwall/gjson v1.6.7 h1:Mb1M9HZCRWEcXQ8ieJo7auYyyiSux6w9XN3AdTpxJrE=
@@ -309,8 +318,9 @@ golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e h1:gsTQYXdTw2Gq7RBsWvlQ91b+aEQ6bXFUngBGuR8sPpI=
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM=
+golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -371,6 +381,7 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81R
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -418,9 +429,11 @@ golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -428,6 +441,7 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3
golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
@@ -559,8 +573,9 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
-google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
+google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
+google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
@@ -573,8 +588,9 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
diff --git a/cmd/aries-agent-rest/go.mod b/cmd/aries-agent-rest/go.mod
index f0e020a2f..e634cae89 100644
--- a/cmd/aries-agent-rest/go.mod
+++ b/cmd/aries-agent-rest/go.mod
@@ -12,10 +12,10 @@ require (
github.com/hyperledger/aries-framework-go v0.1.8-0.20220322085443-50e8f9bd208b
github.com/hyperledger/aries-framework-go/component/storage/leveldb v0.0.0-20220322085443-50e8f9bd208b
github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220322085443-50e8f9bd208b
- github.com/hyperledger/aries-framework-go/spi v0.0.0-20220322085443-50e8f9bd208b
+ github.com/hyperledger/aries-framework-go/spi v0.0.0-20220606124520-53422361c38c
github.com/rs/cors v1.7.0
github.com/spf13/cobra v1.0.0
- github.com/stretchr/testify v1.7.0
+ github.com/stretchr/testify v1.7.2
)
require (
@@ -29,9 +29,9 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/snappy v0.0.3 // indirect
- github.com/google/tink/go v1.6.1-0.20210519071714-58be99b3c4d0 // indirect
- github.com/google/uuid v1.1.2 // indirect
- github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220322085443-50e8f9bd208b // indirect
+ github.com/google/tink/go v1.6.1 // indirect
+ github.com/google/uuid v1.3.0 // indirect
+ github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220606124520-53422361c38c // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a // indirect
github.com/kawamuray/jsonpath v0.0.0-20201211160320-7483bafabd7e // indirect
@@ -40,15 +40,16 @@ require (
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 // indirect
github.com/minio/sha256-simd v0.1.1 // indirect
github.com/mitchellh/mapstructure v1.1.2 // indirect
- github.com/mr-tron/base58 v1.1.3 // indirect
- github.com/multiformats/go-base32 v0.0.3 // indirect
- github.com/multiformats/go-multibase v0.0.1 // indirect
+ github.com/mr-tron/base58 v1.2.0 // indirect
+ github.com/multiformats/go-base32 v0.0.4 // indirect
+ github.com/multiformats/go-base36 v0.1.0 // indirect
+ github.com/multiformats/go-multibase v0.0.3 // indirect
github.com/multiformats/go-multihash v0.0.13 // indirect
github.com/multiformats/go-varint v0.0.5 // indirect
- github.com/piprate/json-gold v0.4.1-0.20210813112359-33b90c4ca86c // indirect
+ github.com/piprate/json-gold v0.4.1 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
- github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect
+ github.com/pquerna/cachecontrol v0.1.0 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/square/go-jose/v3 v3.0.0-20200630053402-0a67ce9b0693 // indirect
@@ -61,10 +62,10 @@ require (
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
- golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e // indirect
- golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect
- google.golang.org/protobuf v1.27.1 // indirect
- gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
+ golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect
+ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect
+ google.golang.org/protobuf v1.28.0 // indirect
+ gopkg.in/yaml.v3 v3.0.1 // indirect
nhooyr.io/websocket v1.8.3 // indirect
)
diff --git a/cmd/aries-agent-rest/go.sum b/cmd/aries-agent-rest/go.sum
index a529e4bcd..23b9b1d18 100644
--- a/cmd/aries-agent-rest/go.sum
+++ b/cmd/aries-agent-rest/go.sum
@@ -177,10 +177,12 @@ github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hf
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
-github.com/google/tink/go v1.6.1-0.20210519071714-58be99b3c4d0 h1:M1kxKye//XPsRJs+DaWPeDgMWK2zuZHWx/easVWhcVc=
github.com/google/tink/go v1.6.1-0.20210519071714-58be99b3c4d0/go.mod h1:IGW53kTgag+st5yPhKKwJ6u2l+SSp5/v9XF7spovjlY=
-github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
+github.com/google/tink/go v1.6.1 h1:t7JHqO8Ath2w2ig5vjwQYJzhGEZymedQc90lQXUBa4I=
+github.com/google/tink/go v1.6.1/go.mod h1:IGW53kTgag+st5yPhKKwJ6u2l+SSp5/v9XF7spovjlY=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
+github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
@@ -214,11 +216,11 @@ github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKe
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
-github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220322085443-50e8f9bd208b h1:cZ1scj+jdCT6IYAXe/62CckfTXv1wr0vnFLh2biH2qQ=
-github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220322085443-50e8f9bd208b/go.mod h1:eIac5lubCy3tw6D0sTluM5U6Bw3inBwUfjX17o2U7PE=
-github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220217153004-1622c70e5767/go.mod h1:HojN6OAh8ZtXBe5X2arcSOe1SLo5Dsjqto8ICjSLQ2g=
-github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220322085443-50e8f9bd208b h1:tq8CYv5vCJBSG2CjWKNt4l1BzZVJUy+GGF4U80fJV8o=
+github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220606124520-53422361c38c h1:8yL/HlgZmfsyXdLJjdE0gBAUjAuW9ZU4I+OiVkil22w=
+github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220606124520-53422361c38c/go.mod h1:JrwivOOQmuXbV1mFWgBGWnfCorOFdfGkpBsYK8dYrfM=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220322085443-50e8f9bd208b/go.mod h1:HojN6OAh8ZtXBe5X2arcSOe1SLo5Dsjqto8ICjSLQ2g=
+github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220428211718-66cc046674a1 h1:vxZ0DlFNLjgxMdBESLZu895AsI1JWL2SJerphwIn8Po=
+github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220428211718-66cc046674a1/go.mod h1:lykx3N+GX+sAWSxO2Ycc4Dz+ynV9b0Fv4NdP+ms4Alc=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
@@ -268,12 +270,17 @@ github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQz
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8=
-github.com/mr-tron/base58 v1.1.3 h1:v+sk57XuaCKGXpWtVBX8YJzO7hMGx4Aajh4TQbdEFdc=
github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
-github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI=
+github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
+github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA=
-github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA=
+github.com/multiformats/go-base32 v0.0.4 h1:+qMh4a2f37b4xTNs6mqitDinryCI+tfO2dRVMN9mjSE=
+github.com/multiformats/go-base32 v0.0.4/go.mod h1:jNLFzjPZtp3aIARHbJRZIaPuspdH0J6q39uUM5pnABM=
+github.com/multiformats/go-base36 v0.1.0 h1:JR6TyF7JjGd3m6FbLU2cOxhC0Li8z8dLNGQ89tUg4F4=
+github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM=
github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs=
+github.com/multiformats/go-multibase v0.0.3 h1:l/B6bJDQjvQ5G52jw4QGSYeOTZoAwIO77RblWplfIqk=
+github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc=
github.com/multiformats/go-multihash v0.0.13 h1:06x+mk/zj1FoMsgNejLpy6QTvJqlSt/BhLEy87zidlc=
github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc=
github.com/multiformats/go-varint v0.0.5 h1:XVZwSo04Cs3j/jS0uAEPpT3JY6DzMcVLLoWOSnCxOjg=
@@ -290,16 +297,18 @@ github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
-github.com/piprate/json-gold v0.4.1-0.20210813112359-33b90c4ca86c h1:F4YQvOA7UTccz06y59KLw4C0iXD28hnKUP9R9zeSe8U=
github.com/piprate/json-gold v0.4.1-0.20210813112359-33b90c4ca86c/go.mod h1:OK1z7UgtBZk06n2cDE2OSq1kffmjFFp5/2yhLLCz9UM=
+github.com/piprate/json-gold v0.4.1 h1:JYbYN36n6YcAYipKy3ttv3X2HDQPeqWqmwta35NPj04=
+github.com/piprate/json-gold v0.4.1/go.mod h1:OK1z7UgtBZk06n2cDE2OSq1kffmjFFp5/2yhLLCz9UM=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
-github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 h1:J9b7z+QKAmPf4YLrFg6oQUotqHQeUNWwkvo7jZp1GLU=
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
+github.com/pquerna/cachecontrol v0.1.0 h1:yJMy84ti9h/+OEWa752kBTKv4XC30OtVVHYv/8cTqKc=
+github.com/pquerna/cachecontrol v0.1.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
@@ -340,8 +349,9 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s=
+github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
github.com/teserakt-io/golang-ed25519 v0.0.0-20210104091850-3888c087a4c8 h1:RBkacARv7qY5laaXGlF4wFB/tk5rnthhPb8oIBGoagY=
@@ -391,8 +401,9 @@ golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e h1:gsTQYXdTw2Gq7RBsWvlQ91b+aEQ6bXFUngBGuR8sPpI=
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM=
+golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -455,8 +466,9 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE=
+golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -508,17 +520,20 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201211090839-8ad439b19e0f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
-golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
@@ -652,8 +667,9 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
-google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
+google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
+google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -672,8 +688,9 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
diff --git a/cmd/aries-js-worker/go.mod b/cmd/aries-js-worker/go.mod
index 061a28148..8c38c49fa 100644
--- a/cmd/aries-js-worker/go.mod
+++ b/cmd/aries-js-worker/go.mod
@@ -7,12 +7,12 @@ module github.com/hyperledger/aries-framework-go/cmd/aries-js-worker
go 1.17
require (
- github.com/google/uuid v1.1.2
+ github.com/google/uuid v1.3.0
github.com/hyperledger/aries-framework-go v0.1.8-0.20220322085443-50e8f9bd208b
github.com/hyperledger/aries-framework-go/component/storage/indexeddb v0.1.8-0.20220322085443-50e8f9bd208b
- github.com/hyperledger/aries-framework-go/spi v0.0.0-20220322085443-50e8f9bd208b
+ github.com/hyperledger/aries-framework-go/spi v0.0.0-20220606124520-53422361c38c
github.com/mitchellh/mapstructure v1.3.0
- github.com/stretchr/testify v1.7.0
+ github.com/stretchr/testify v1.7.2
)
require (
@@ -27,9 +27,9 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/snappy v0.0.1 // indirect
- github.com/google/tink/go v1.6.1-0.20210519071714-58be99b3c4d0 // indirect
+ github.com/google/tink/go v1.6.1 // indirect
github.com/gorilla/mux v1.7.3 // indirect
- github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220322085443-50e8f9bd208b // indirect
+ github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220606124520-53422361c38c // indirect
github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220322085443-50e8f9bd208b // indirect
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a // indirect
github.com/kawamuray/jsonpath v0.0.0-20201211160320-7483bafabd7e // indirect
@@ -37,15 +37,16 @@ require (
github.com/klauspost/compress v1.10.0 // indirect
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 // indirect
github.com/minio/sha256-simd v0.1.1 // indirect
- github.com/mr-tron/base58 v1.1.3 // indirect
- github.com/multiformats/go-base32 v0.0.3 // indirect
- github.com/multiformats/go-multibase v0.0.1 // indirect
+ github.com/mr-tron/base58 v1.2.0 // indirect
+ github.com/multiformats/go-base32 v0.0.4 // indirect
+ github.com/multiformats/go-base36 v0.1.0 // indirect
+ github.com/multiformats/go-multibase v0.0.3 // indirect
github.com/multiformats/go-multihash v0.0.13 // indirect
github.com/multiformats/go-varint v0.0.5 // indirect
- github.com/piprate/json-gold v0.4.1-0.20210813112359-33b90c4ca86c // indirect
+ github.com/piprate/json-gold v0.4.1 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
- github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect
+ github.com/pquerna/cachecontrol v0.1.0 // indirect
github.com/rs/cors v1.7.0 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/square/go-jose/v3 v3.0.0-20200630053402-0a67ce9b0693 // indirect
@@ -57,10 +58,10 @@ require (
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
- golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e // indirect
- golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect
- google.golang.org/protobuf v1.27.1 // indirect
- gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
+ golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect
+ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect
+ google.golang.org/protobuf v1.28.0 // indirect
+ gopkg.in/yaml.v3 v3.0.1 // indirect
nhooyr.io/websocket v1.8.3 // indirect
)
diff --git a/cmd/aries-js-worker/go.sum b/cmd/aries-js-worker/go.sum
index 59fafb599..8abf90c9d 100644
--- a/cmd/aries-js-worker/go.sum
+++ b/cmd/aries-js-worker/go.sum
@@ -150,10 +150,12 @@ github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hf
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
-github.com/google/tink/go v1.6.1-0.20210519071714-58be99b3c4d0 h1:M1kxKye//XPsRJs+DaWPeDgMWK2zuZHWx/easVWhcVc=
github.com/google/tink/go v1.6.1-0.20210519071714-58be99b3c4d0/go.mod h1:IGW53kTgag+st5yPhKKwJ6u2l+SSp5/v9XF7spovjlY=
-github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
+github.com/google/tink/go v1.6.1 h1:t7JHqO8Ath2w2ig5vjwQYJzhGEZymedQc90lQXUBa4I=
+github.com/google/tink/go v1.6.1/go.mod h1:IGW53kTgag+st5yPhKKwJ6u2l+SSp5/v9XF7spovjlY=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
+github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
@@ -226,12 +228,17 @@ github.com/mitchellh/mapstructure v1.3.0 h1:iDwIio/3gk2QtLLEsqU5lInaMzos0hDTz8a6
github.com/mitchellh/mapstructure v1.3.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8=
-github.com/mr-tron/base58 v1.1.3 h1:v+sk57XuaCKGXpWtVBX8YJzO7hMGx4Aajh4TQbdEFdc=
github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
-github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI=
+github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
+github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA=
-github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA=
+github.com/multiformats/go-base32 v0.0.4 h1:+qMh4a2f37b4xTNs6mqitDinryCI+tfO2dRVMN9mjSE=
+github.com/multiformats/go-base32 v0.0.4/go.mod h1:jNLFzjPZtp3aIARHbJRZIaPuspdH0J6q39uUM5pnABM=
+github.com/multiformats/go-base36 v0.1.0 h1:JR6TyF7JjGd3m6FbLU2cOxhC0Li8z8dLNGQ89tUg4F4=
+github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM=
github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs=
+github.com/multiformats/go-multibase v0.0.3 h1:l/B6bJDQjvQ5G52jw4QGSYeOTZoAwIO77RblWplfIqk=
+github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc=
github.com/multiformats/go-multihash v0.0.13 h1:06x+mk/zj1FoMsgNejLpy6QTvJqlSt/BhLEy87zidlc=
github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc=
github.com/multiformats/go-varint v0.0.5 h1:XVZwSo04Cs3j/jS0uAEPpT3JY6DzMcVLLoWOSnCxOjg=
@@ -243,15 +250,17 @@ github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
-github.com/piprate/json-gold v0.4.1-0.20210813112359-33b90c4ca86c h1:F4YQvOA7UTccz06y59KLw4C0iXD28hnKUP9R9zeSe8U=
github.com/piprate/json-gold v0.4.1-0.20210813112359-33b90c4ca86c/go.mod h1:OK1z7UgtBZk06n2cDE2OSq1kffmjFFp5/2yhLLCz9UM=
+github.com/piprate/json-gold v0.4.1 h1:JYbYN36n6YcAYipKy3ttv3X2HDQPeqWqmwta35NPj04=
+github.com/piprate/json-gold v0.4.1/go.mod h1:OK1z7UgtBZk06n2cDE2OSq1kffmjFFp5/2yhLLCz9UM=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
-github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 h1:J9b7z+QKAmPf4YLrFg6oQUotqHQeUNWwkvo7jZp1GLU=
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
+github.com/pquerna/cachecontrol v0.1.0 h1:yJMy84ti9h/+OEWa752kBTKv4XC30OtVVHYv/8cTqKc=
+github.com/pquerna/cachecontrol v0.1.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=
@@ -267,8 +276,9 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s=
+github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
github.com/teserakt-io/golang-ed25519 v0.0.0-20210104091850-3888c087a4c8 h1:RBkacARv7qY5laaXGlF4wFB/tk5rnthhPb8oIBGoagY=
github.com/teserakt-io/golang-ed25519 v0.0.0-20210104091850-3888c087a4c8/go.mod h1:9PdLyPiZIiW3UopXyRnPYyjUXSpiQNHRLu8fOsR3o8M=
github.com/tidwall/gjson v1.6.7 h1:Mb1M9HZCRWEcXQ8ieJo7auYyyiSux6w9XN3AdTpxJrE=
@@ -307,8 +317,9 @@ golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e h1:gsTQYXdTw2Gq7RBsWvlQ91b+aEQ6bXFUngBGuR8sPpI=
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM=
+golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -369,6 +380,7 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81R
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -416,9 +428,11 @@ golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -426,6 +440,7 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3
golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
@@ -557,8 +572,9 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
-google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
+google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
+google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
@@ -571,8 +587,9 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
diff --git a/component/storage/edv/go.sum b/component/storage/edv/go.sum
index 1fbe3f026..797908a5f 100644
--- a/component/storage/edv/go.sum
+++ b/component/storage/edv/go.sum
@@ -216,8 +216,6 @@ github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210603182844-3
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210807121559-b41545a4f1e8/go.mod h1:3idbNcBl2wdRaETayzpY95KK5SfSzwXb5uqLW/Ldh0g=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210820153043-8b6f36d10ab9/go.mod h1:7jEZdg455syX4f+ozLgwhYfIuiEQ/TgdIoOyALMwPG0=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220217153004-1622c70e5767/go.mod h1:HojN6OAh8ZtXBe5X2arcSOe1SLo5Dsjqto8ICjSLQ2g=
-github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220322085443-50e8f9bd208b h1:tq8CYv5vCJBSG2CjWKNt4l1BzZVJUy+GGF4U80fJV8o=
-github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220322085443-50e8f9bd208b/go.mod h1:HojN6OAh8ZtXBe5X2arcSOe1SLo5Dsjqto8ICjSLQ2g=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220428211718-66cc046674a1 h1:vxZ0DlFNLjgxMdBESLZu895AsI1JWL2SJerphwIn8Po=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220428211718-66cc046674a1/go.mod h1:lykx3N+GX+sAWSxO2Ycc4Dz+ynV9b0Fv4NdP+ms4Alc=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
diff --git a/go.mod b/go.mod
index e0f3fd491..76de95148 100644
--- a/go.mod
+++ b/go.mod
@@ -14,30 +14,30 @@ require (
github.com/cenkalti/backoff/v4 v4.0.2
github.com/golang/mock v1.4.4
github.com/golang/protobuf v1.5.2
- github.com/google/tink/go v1.6.1-0.20210519071714-58be99b3c4d0
- github.com/google/uuid v1.1.2
+ github.com/google/tink/go v1.6.1
+ github.com/google/uuid v1.3.0
github.com/gorilla/mux v1.7.3
- github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220322085443-50e8f9bd208b
+ github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220606124520-53422361c38c
github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220322085443-50e8f9bd208b
- github.com/hyperledger/aries-framework-go/spi v0.0.0-20220322085443-50e8f9bd208b
+ github.com/hyperledger/aries-framework-go/spi v0.0.0-20220606124520-53422361c38c
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a
github.com/kawamuray/jsonpath v0.0.0-20201211160320-7483bafabd7e
github.com/kilic/bls12-381 v0.1.1-0.20210503002446-7b7597926c69
github.com/mitchellh/mapstructure v1.1.2
- github.com/multiformats/go-multibase v0.0.1
+ github.com/multiformats/go-multibase v0.0.3
github.com/multiformats/go-multihash v0.0.13
- github.com/piprate/json-gold v0.4.1-0.20210813112359-33b90c4ca86c
+ github.com/piprate/json-gold v0.4.1
github.com/pkg/errors v0.9.1
github.com/rs/cors v1.7.0
github.com/square/go-jose/v3 v3.0.0-20200630053402-0a67ce9b0693
- github.com/stretchr/testify v1.7.0
+ github.com/stretchr/testify v1.7.2
github.com/teserakt-io/golang-ed25519 v0.0.0-20210104091850-3888c087a4c8
github.com/tidwall/gjson v1.6.7
github.com/tidwall/sjson v1.1.4
github.com/xeipuuv/gojsonschema v1.2.0
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e
- golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c
- google.golang.org/protobuf v1.27.1
+ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a
+ google.golang.org/protobuf v1.28.0
nhooyr.io/websocket v1.8.3
)
@@ -48,17 +48,18 @@ require (
github.com/klauspost/compress v1.10.0 // indirect
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 // indirect
github.com/minio/sha256-simd v0.1.1 // indirect
- github.com/mr-tron/base58 v1.1.3 // indirect
- github.com/multiformats/go-base32 v0.0.3 // indirect
+ github.com/mr-tron/base58 v1.2.0 // indirect
+ github.com/multiformats/go-base32 v0.0.4 // indirect
+ github.com/multiformats/go-base36 v0.1.0 // indirect
github.com/multiformats/go-varint v0.0.5 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
- github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect
+ github.com/pquerna/cachecontrol v0.1.0 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/tidwall/match v1.0.3 // indirect
github.com/tidwall/pretty v1.0.2 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
- gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
+ gopkg.in/yaml.v3 v3.0.1 // indirect
)
go 1.17
diff --git a/go.sum b/go.sum
index 7c03f50a2..a51e17466 100644
--- a/go.sum
+++ b/go.sum
@@ -153,10 +153,12 @@ github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hf
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/tink/go v1.5.0/go.mod h1:wSm19SFGYgyFRF3jqrfcMatRxFRjQ7n0Ly7Vx4ndQXQ=
-github.com/google/tink/go v1.6.1-0.20210519071714-58be99b3c4d0 h1:M1kxKye//XPsRJs+DaWPeDgMWK2zuZHWx/easVWhcVc=
github.com/google/tink/go v1.6.1-0.20210519071714-58be99b3c4d0/go.mod h1:IGW53kTgag+st5yPhKKwJ6u2l+SSp5/v9XF7spovjlY=
-github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
+github.com/google/tink/go v1.6.1 h1:t7JHqO8Ath2w2ig5vjwQYJzhGEZymedQc90lQXUBa4I=
+github.com/google/tink/go v1.6.1/go.mod h1:IGW53kTgag+st5yPhKKwJ6u2l+SSp5/v9XF7spovjlY=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
+github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
@@ -188,16 +190,19 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO
github.com/hyperledger/aries-framework-go v0.1.7-0.20210421203733-b5dfd703a8fc/go.mod h1:tBgxVOKcNero3QI21iNf3oxxHkgRMDOby937cqHEvW4=
github.com/hyperledger/aries-framework-go v0.1.7-0.20210603210127-e57b8c94e3cf/go.mod h1:h6L+YoXtw90OZrH2IequxukIGwzfSpz8pUueQ9T5KqI=
github.com/hyperledger/aries-framework-go v0.1.8-0.20220217153004-1622c70e5767/go.mod h1:rBMOJVwyHyYbOqbb3IB/ExBkHyvFLht/W81s24GmjcE=
+github.com/hyperledger/aries-framework-go v0.1.8-0.20220322085443-50e8f9bd208b/go.mod h1:bqeLa1s8fQ7YueGOOk0Q+r48FGF7sd8GEaS/CyEo/iY=
github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20210520055214-ae429bb89bf7/go.mod h1:7D+Y5J9cIsUrMGFAsIED+3bAPNjxp6ggXo0/kT5N6BI=
github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20210820175050-dcc7a225178d/go.mod h1:i40JkMHCh9cHHxSc1SYznO3xDH6ly5CE0B3vPYZVeWI=
-github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220322085443-50e8f9bd208b h1:cZ1scj+jdCT6IYAXe/62CckfTXv1wr0vnFLh2biH2qQ=
-github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220322085443-50e8f9bd208b/go.mod h1:eIac5lubCy3tw6D0sTluM5U6Bw3inBwUfjX17o2U7PE=
+github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220308060532-714cd5c18552/go.mod h1:eIac5lubCy3tw6D0sTluM5U6Bw3inBwUfjX17o2U7PE=
+github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220606124520-53422361c38c h1:8yL/HlgZmfsyXdLJjdE0gBAUjAuW9ZU4I+OiVkil22w=
+github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220606124520-53422361c38c/go.mod h1:JrwivOOQmuXbV1mFWgBGWnfCorOFdfGkpBsYK8dYrfM=
github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20210409151411-eeeb8508bd87/go.mod h1:kJT7bcaKsvk1lMp2jqS8srF+ZUie2H4MoPbL2V29dgA=
github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20210421203733-b5dfd703a8fc/go.mod h1:uGc7F3tXQIY6xjs8VEI6/oxp4ZDXDfGjPMCTgax5Zhc=
github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20210520055214-ae429bb89bf7/go.mod h1:aP6VnxeSbmD1OcV2f8y0dRV9fkIZp/+mzmgKxxmSJG4=
github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20210807121559-b41545a4f1e8/go.mod h1:k8CjDLBLxygTEj3D077OeH4SJsVE3mK60AyeO/C9sxs=
github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20210820175050-dcc7a225178d/go.mod h1:wdgGPwXzih+QD2Q4nvMnGO0dm0D0rxmzQcSNLcW6fcg=
github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220217153004-1622c70e5767/go.mod h1:yLgRpVlZ2heeeOpTgvEnG/yHL9q1keUu5ILQ6s2qpLU=
+github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220308060532-714cd5c18552/go.mod h1:yLgRpVlZ2heeeOpTgvEnG/yHL9q1keUu5ILQ6s2qpLU=
github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220322085443-50e8f9bd208b h1:IoD7+sHQRLMouwHjhrOj5vhg+rPt/aKl4P+WiBZVHVk=
github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220322085443-50e8f9bd208b/go.mod h1:yLgRpVlZ2heeeOpTgvEnG/yHL9q1keUu5ILQ6s2qpLU=
github.com/hyperledger/aries-framework-go/spi v0.0.0-20210320144851-40976de98ccf/go.mod h1:fDr9wW00GJJl1lR1SFHmJW8utIocdvjO5RNhAYS05EY=
@@ -216,16 +221,19 @@ github.com/hyperledger/aries-framework-go/spi v0.0.0-20210820153043-8b6f36d10ab9
github.com/hyperledger/aries-framework-go/spi v0.0.0-20210820175050-dcc7a225178d/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
github.com/hyperledger/aries-framework-go/spi v0.0.0-20211203210130-e927c9ed581a/go.mod h1:dBYKKD8U8U9o0g5BdNFFaRtjt9KTkiAYfQt+TTp+w1o=
github.com/hyperledger/aries-framework-go/spi v0.0.0-20220217153004-1622c70e5767/go.mod h1:4bD5c5fj5K7rkQurVa/8I8+TfNcI4bxIBzaUNcxTOTg=
-github.com/hyperledger/aries-framework-go/spi v0.0.0-20220322085443-50e8f9bd208b h1:Fo9mK3eB+TiYu2/hbTWtt0kWg9j1QRqnnbQQqaytJzE=
+github.com/hyperledger/aries-framework-go/spi v0.0.0-20220308060532-714cd5c18552/go.mod h1:4bD5c5fj5K7rkQurVa/8I8+TfNcI4bxIBzaUNcxTOTg=
github.com/hyperledger/aries-framework-go/spi v0.0.0-20220322085443-50e8f9bd208b/go.mod h1:4bD5c5fj5K7rkQurVa/8I8+TfNcI4bxIBzaUNcxTOTg=
+github.com/hyperledger/aries-framework-go/spi v0.0.0-20220606124520-53422361c38c h1:4JSde5+80U+W8IxwNt/Dd/3PPEIGYTI3RbjFXOi4o1g=
+github.com/hyperledger/aries-framework-go/spi v0.0.0-20220606124520-53422361c38c/go.mod h1:4bD5c5fj5K7rkQurVa/8I8+TfNcI4bxIBzaUNcxTOTg=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210324232048-34ff560ed041/go.mod h1:eKGEEe+PJNDQo7kVif3sUKBWwnsQDkE3gD/QlpmukcQ=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210409151411-eeeb8508bd87/go.mod h1:JHzDtgJLd0134iLFXLxGBjJF+Z+TgiElA/5oVgMazts=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210421203733-b5dfd703a8fc/go.mod h1:asiCVCtH/nocWKhZRMz12aFgdUh8lRHqKis0M8Ei/4I=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210603182844-353ecb34cf4d/go.mod h1:J0SlvlnETEdYojUW4om/UINH0Uobmbtw46cH4DGXv5g=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210807121559-b41545a4f1e8/go.mod h1:3idbNcBl2wdRaETayzpY95KK5SfSzwXb5uqLW/Ldh0g=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210820153043-8b6f36d10ab9/go.mod h1:7jEZdg455syX4f+ozLgwhYfIuiEQ/TgdIoOyALMwPG0=
-github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220217153004-1622c70e5767 h1:XyfULUaaWSj+JRaILaxTUHFh0CujzODJ5P4qJNjZM+w=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220217153004-1622c70e5767/go.mod h1:HojN6OAh8ZtXBe5X2arcSOe1SLo5Dsjqto8ICjSLQ2g=
+github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220428211718-66cc046674a1 h1:vxZ0DlFNLjgxMdBESLZu895AsI1JWL2SJerphwIn8Po=
+github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220428211718-66cc046674a1/go.mod h1:lykx3N+GX+sAWSxO2Ycc4Dz+ynV9b0Fv4NdP+ms4Alc=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
@@ -267,12 +275,17 @@ github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQz
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8=
-github.com/mr-tron/base58 v1.1.3 h1:v+sk57XuaCKGXpWtVBX8YJzO7hMGx4Aajh4TQbdEFdc=
github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
-github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI=
+github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
+github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA=
-github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA=
+github.com/multiformats/go-base32 v0.0.4 h1:+qMh4a2f37b4xTNs6mqitDinryCI+tfO2dRVMN9mjSE=
+github.com/multiformats/go-base32 v0.0.4/go.mod h1:jNLFzjPZtp3aIARHbJRZIaPuspdH0J6q39uUM5pnABM=
+github.com/multiformats/go-base36 v0.1.0 h1:JR6TyF7JjGd3m6FbLU2cOxhC0Li8z8dLNGQ89tUg4F4=
+github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM=
github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs=
+github.com/multiformats/go-multibase v0.0.3 h1:l/B6bJDQjvQ5G52jw4QGSYeOTZoAwIO77RblWplfIqk=
+github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc=
github.com/multiformats/go-multihash v0.0.13 h1:06x+mk/zj1FoMsgNejLpy6QTvJqlSt/BhLEy87zidlc=
github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc=
github.com/multiformats/go-varint v0.0.5 h1:XVZwSo04Cs3j/jS0uAEPpT3JY6DzMcVLLoWOSnCxOjg=
@@ -285,15 +298,17 @@ github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/piprate/json-gold v0.4.0/go.mod h1:OK1z7UgtBZk06n2cDE2OSq1kffmjFFp5/2yhLLCz9UM=
-github.com/piprate/json-gold v0.4.1-0.20210813112359-33b90c4ca86c h1:F4YQvOA7UTccz06y59KLw4C0iXD28hnKUP9R9zeSe8U=
github.com/piprate/json-gold v0.4.1-0.20210813112359-33b90c4ca86c/go.mod h1:OK1z7UgtBZk06n2cDE2OSq1kffmjFFp5/2yhLLCz9UM=
+github.com/piprate/json-gold v0.4.1 h1:JYbYN36n6YcAYipKy3ttv3X2HDQPeqWqmwta35NPj04=
+github.com/piprate/json-gold v0.4.1/go.mod h1:OK1z7UgtBZk06n2cDE2OSq1kffmjFFp5/2yhLLCz9UM=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
-github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 h1:J9b7z+QKAmPf4YLrFg6oQUotqHQeUNWwkvo7jZp1GLU=
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
+github.com/pquerna/cachecontrol v0.1.0 h1:yJMy84ti9h/+OEWa752kBTKv4XC30OtVVHYv/8cTqKc=
+github.com/pquerna/cachecontrol v0.1.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=
@@ -309,8 +324,9 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s=
+github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
github.com/teserakt-io/golang-ed25519 v0.0.0-20200315192543-8255be791ce4/go.mod h1:9PdLyPiZIiW3UopXyRnPYyjUXSpiQNHRLu8fOsR3o8M=
github.com/teserakt-io/golang-ed25519 v0.0.0-20210104091850-3888c087a4c8 h1:RBkacARv7qY5laaXGlF4wFB/tk5rnthhPb8oIBGoagY=
github.com/teserakt-io/golang-ed25519 v0.0.0-20210104091850-3888c087a4c8/go.mod h1:9PdLyPiZIiW3UopXyRnPYyjUXSpiQNHRLu8fOsR3o8M=
@@ -462,8 +478,9 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20201211090839-8ad439b19e0f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -602,8 +619,9 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
-google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
+google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
+google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
@@ -616,8 +634,9 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
diff --git a/test/bdd/go.mod b/test/bdd/go.mod
index 190e54ed6..2e0cf9388 100644
--- a/test/bdd/go.mod
+++ b/test/bdd/go.mod
@@ -11,16 +11,16 @@ require (
github.com/cenkalti/backoff/v4 v4.0.2
github.com/cucumber/godog v0.8.1
github.com/fsouza/go-dockerclient v1.6.6
- github.com/google/uuid v1.1.2
+ github.com/google/uuid v1.3.0
github.com/gorilla/mux v1.8.0
github.com/hyperledger/aries-framework-go v0.1.8-0.20220322085443-50e8f9bd208b
github.com/hyperledger/aries-framework-go/component/storage/leveldb v0.0.0-20220322085443-50e8f9bd208b
github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220322085443-50e8f9bd208b
- github.com/hyperledger/aries-framework-go/spi v0.0.0-20220322085443-50e8f9bd208b
+ github.com/hyperledger/aries-framework-go/spi v0.0.0-20220606124520-53422361c38c
github.com/moby/sys/mount v0.2.0 // indirect
github.com/moby/term v0.0.0-20201110203204-bea5bbe245bf // indirect
github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2
- github.com/piprate/json-gold v0.4.1-0.20210813112359-33b90c4ca86c
+ github.com/piprate/json-gold v0.4.1
github.com/teserakt-io/golang-ed25519 v0.0.0-20210104091850-3888c087a4c8
github.com/trustbloc/sidetree-core-go v0.6.0
nhooyr.io/websocket v1.8.3
@@ -47,7 +47,8 @@ require (
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/snappy v0.0.3 // indirect
- github.com/google/tink/go v1.6.1-0.20210519071714-58be99b3c4d0 // indirect
+ github.com/google/tink/go v1.6.1 // indirect
+ github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220428211718-66cc046674a1 // indirect
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a // indirect
github.com/kawamuray/jsonpath v0.0.0-20201211160320-7483bafabd7e // indirect
github.com/kilic/bls12-381 v0.1.1-0.20210503002446-7b7597926c69 // indirect
@@ -57,9 +58,10 @@ require (
github.com/mitchellh/mapstructure v1.1.2 // indirect
github.com/moby/sys/mountinfo v0.4.0 // indirect
github.com/morikuni/aec v1.0.0 // indirect
- github.com/mr-tron/base58 v1.1.3 // indirect
- github.com/multiformats/go-base32 v0.0.3 // indirect
- github.com/multiformats/go-multibase v0.0.1 // indirect
+ github.com/mr-tron/base58 v1.2.0 // indirect
+ github.com/multiformats/go-base32 v0.0.4 // indirect
+ github.com/multiformats/go-base36 v0.1.0 // indirect
+ github.com/multiformats/go-multibase v0.0.3 // indirect
github.com/multiformats/go-multihash v0.0.14 // indirect
github.com/multiformats/go-varint v0.0.5 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
@@ -67,12 +69,12 @@ require (
github.com/opencontainers/runc v0.1.1 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
- github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect
+ github.com/pquerna/cachecontrol v0.1.0 // indirect
github.com/rs/cors v1.7.0 // indirect
github.com/sirupsen/logrus v1.7.0 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/square/go-jose/v3 v3.0.0-20200630053402-0a67ce9b0693 // indirect
- github.com/stretchr/testify v1.7.0 // indirect
+ github.com/stretchr/testify v1.7.2 // indirect
github.com/syndtr/goleveldb v1.0.0 // indirect
github.com/tidwall/gjson v1.6.7 // indirect
github.com/tidwall/match v1.0.3 // indirect
@@ -83,11 +85,11 @@ require (
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
go.opencensus.io v0.22.5 // indirect
- golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e // indirect
+ golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a // indirect
- golang.org/x/sys v0.0.0-20210910150752-751e447fb3d0 // indirect
- google.golang.org/protobuf v1.27.1 // indirect
- gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
+ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect
+ google.golang.org/protobuf v1.28.0 // indirect
+ gopkg.in/yaml.v3 v3.0.1 // indirect
)
replace (
diff --git a/test/bdd/go.sum b/test/bdd/go.sum
index 85dc5a153..894418714 100644
--- a/test/bdd/go.sum
+++ b/test/bdd/go.sum
@@ -238,10 +238,12 @@ github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hf
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
-github.com/google/tink/go v1.6.1-0.20210519071714-58be99b3c4d0 h1:M1kxKye//XPsRJs+DaWPeDgMWK2zuZHWx/easVWhcVc=
github.com/google/tink/go v1.6.1-0.20210519071714-58be99b3c4d0/go.mod h1:IGW53kTgag+st5yPhKKwJ6u2l+SSp5/v9XF7spovjlY=
-github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
+github.com/google/tink/go v1.6.1 h1:t7JHqO8Ath2w2ig5vjwQYJzhGEZymedQc90lQXUBa4I=
+github.com/google/tink/go v1.6.1/go.mod h1:IGW53kTgag+st5yPhKKwJ6u2l+SSp5/v9XF7spovjlY=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
+github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gopherjs/gopherjs v0.0.0-20200209183636-89e6cbcd0b6d/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
@@ -277,7 +279,7 @@ github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKe
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
-github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220322085443-50e8f9bd208b/go.mod h1:eIac5lubCy3tw6D0sTluM5U6Bw3inBwUfjX17o2U7PE=
+github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220606124520-53422361c38c/go.mod h1:JrwivOOQmuXbV1mFWgBGWnfCorOFdfGkpBsYK8dYrfM=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
@@ -340,12 +342,17 @@ github.com/moby/term v0.0.0-20201110203204-bea5bbe245bf/go.mod h1:FBS0z0QWA44HXy
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8=
-github.com/mr-tron/base58 v1.1.3 h1:v+sk57XuaCKGXpWtVBX8YJzO7hMGx4Aajh4TQbdEFdc=
github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
-github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI=
+github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
+github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA=
-github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA=
+github.com/multiformats/go-base32 v0.0.4 h1:+qMh4a2f37b4xTNs6mqitDinryCI+tfO2dRVMN9mjSE=
+github.com/multiformats/go-base32 v0.0.4/go.mod h1:jNLFzjPZtp3aIARHbJRZIaPuspdH0J6q39uUM5pnABM=
+github.com/multiformats/go-base36 v0.1.0 h1:JR6TyF7JjGd3m6FbLU2cOxhC0Li8z8dLNGQ89tUg4F4=
+github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM=
github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs=
+github.com/multiformats/go-multibase v0.0.3 h1:l/B6bJDQjvQ5G52jw4QGSYeOTZoAwIO77RblWplfIqk=
+github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc=
github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc=
github.com/multiformats/go-multihash v0.0.14 h1:QoBceQYQQtNUuf6s7wHxnE2c8bhbMqhfGzNI032se/I=
github.com/multiformats/go-multihash v0.0.14/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc=
@@ -381,8 +388,9 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9
github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 h1:JhzVVoYvbOACxoUmOs6V/G4D5nPVUW73rKvXxP4XUJc=
github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
-github.com/piprate/json-gold v0.4.1-0.20210813112359-33b90c4ca86c h1:F4YQvOA7UTccz06y59KLw4C0iXD28hnKUP9R9zeSe8U=
github.com/piprate/json-gold v0.4.1-0.20210813112359-33b90c4ca86c/go.mod h1:OK1z7UgtBZk06n2cDE2OSq1kffmjFFp5/2yhLLCz9UM=
+github.com/piprate/json-gold v0.4.1 h1:JYbYN36n6YcAYipKy3ttv3X2HDQPeqWqmwta35NPj04=
+github.com/piprate/json-gold v0.4.1/go.mod h1:OK1z7UgtBZk06n2cDE2OSq1kffmjFFp5/2yhLLCz9UM=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -391,8 +399,9 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
-github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 h1:J9b7z+QKAmPf4YLrFg6oQUotqHQeUNWwkvo7jZp1GLU=
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
+github.com/pquerna/cachecontrol v0.1.0 h1:yJMy84ti9h/+OEWa752kBTKv4XC30OtVVHYv/8cTqKc=
+github.com/pquerna/cachecontrol v0.1.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
@@ -440,8 +449,9 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s=
+github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
github.com/teserakt-io/golang-ed25519 v0.0.0-20210104091850-3888c087a4c8 h1:RBkacARv7qY5laaXGlF4wFB/tk5rnthhPb8oIBGoagY=
@@ -504,8 +514,9 @@ golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e h1:gsTQYXdTw2Gq7RBsWvlQ91b+aEQ6bXFUngBGuR8sPpI=
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM=
+golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -569,8 +580,9 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE=
+golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -635,10 +647,11 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201211090839-8ad439b19e0f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210910150752-751e447fb3d0 h1:xrCZDmdtoloIiooiA9q0OQb9r8HejIHYoHGhGCe1pGg=
-golang.org/x/sys v0.0.0-20210910150752-751e447fb3d0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -646,8 +659,9 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
-golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
@@ -784,8 +798,9 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
-google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
+google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
+google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
@@ -806,8 +821,9 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
gotest.tools/v3 v3.0.2 h1:kG1BFyqVHuQoVQiR1bWGnfz/fmHvvuiSPIV7rvl360E=
From d2557117d0a3a098a02344a2ce45e05a0e1c2c95 Mon Sep 17 00:00:00 2001
From: Volodymyr Kubiv <62515092+vkubiv@users.noreply.github.com>
Date: Tue, 7 Jun 2022 17:26:45 +0300
Subject: [PATCH 44/54] feat: separate cache from token. (#3249)
Signed-off-by: Volodymyr Kubiv
Co-authored-by: Sudesh Shetty
---
pkg/wallet/contents.go | 9 +-
pkg/wallet/contents_test.go | 91 +++++++++++---------
pkg/wallet/kmsclient.go | 98 +++++-----------------
pkg/wallet/kmsclient_test.go | 157 +++++++----------------------------
pkg/wallet/profile_test.go | 6 --
pkg/wallet/session.go | 144 ++++++++++++++++++++++++++++++++
pkg/wallet/sesson_test.go | 91 ++++++++++++++++++++
pkg/wallet/storage.go | 17 +---
pkg/wallet/storage_test.go | 41 ++++-----
pkg/wallet/wallet.go | 33 ++++----
pkg/wallet/wallet_test.go | 140 ++++++++++++++++++++++---------
11 files changed, 476 insertions(+), 351 deletions(-)
create mode 100644 pkg/wallet/session.go
create mode 100644 pkg/wallet/sesson_test.go
diff --git a/pkg/wallet/contents.go b/pkg/wallet/contents.go
index e5dcc4aa5..6cd6ea658 100644
--- a/pkg/wallet/contents.go
+++ b/pkg/wallet/contents.go
@@ -21,6 +21,7 @@ import (
"github.com/hyperledger/aries-framework-go/pkg/doc/did"
"github.com/hyperledger/aries-framework-go/pkg/framework/aries/api/vdr"
+ "github.com/hyperledger/aries-framework-go/pkg/kms"
"github.com/hyperledger/aries-framework-go/spi/storage"
)
@@ -122,8 +123,8 @@ func newContentStore(p storage.Provider, pr *profile) *contentStore {
return contents
}
-func (cs *contentStore) Open(auth string, opts *unlockOpts) error {
- store, err := cs.provider.OpenStore(auth, opts, storage.StoreConfiguration{TagNames: []string{
+func (cs *contentStore) Open(keyMgr kms.KeyManager, opts *unlockOpts) error {
+ store, err := cs.provider.OpenStore(keyMgr, opts, storage.StoreConfiguration{TagNames: []string{
Collection.Name(), Credential.Name(), Connection.Name(), DIDResolutionResponse.Name(), Connection.Name(), Key.Name(),
}})
if err != nil {
@@ -146,9 +147,9 @@ func (cs *contentStore) Open(auth string, opts *unlockOpts) error {
func (cs *contentStore) updateStoreHandles(store storage.Store) {
// give access to store only when auth is valid & not expired.
cs.open = func(auth string) (storage.Store, error) {
- _, err := keyManager().getKeyManger(auth)
+ _, err := sessionManager().getSession(auth)
if err != nil {
- return nil, ErrInvalidAuthToken
+ return nil, err
}
return store, nil
diff --git a/pkg/wallet/contents_test.go b/pkg/wallet/contents_test.go
index 5a3cdf75d..70650cff2 100644
--- a/pkg/wallet/contents_test.go
+++ b/pkg/wallet/contents_test.go
@@ -184,10 +184,10 @@ func TestContentTypes(t *testing.T) {
}
func TestContentStores(t *testing.T) {
- token := uuid.New().String()
+ keyMgr := &mockkms.KeyManager{}
- require.NoError(t, keyManager().saveKeyManger(uuid.New().String(), token,
- &mockkms.KeyManager{}, 1000*time.Millisecond))
+ token, e := sessionManager().createSession(uuid.New().String(), keyMgr, 5*time.Second)
+ require.NoError(t, e)
t.Run("create new content store - success", func(t *testing.T) {
sp := getMockStorageProvider()
@@ -198,7 +198,7 @@ func TestContentStores(t *testing.T) {
require.Empty(t, sp.config.TagNames)
// open store
- require.NoError(t, contentStore.Open(token, &unlockOpts{}))
+ require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
require.EqualValues(t, sp.config.TagNames,
[]string{"collection", "credential", "connection", "didResolutionResponse", "connection", "key"})
@@ -229,11 +229,12 @@ func TestContentStores(t *testing.T) {
},
}
- tkn, err := keyManager().createKeyManager(profileInfo, sp, &unlockOpts{passphrase: samplePassPhrase})
+ kmgr, err := keyManager().createKeyManager(profileInfo, sp, &unlockOpts{passphrase: samplePassPhrase})
+ require.NotEmpty(t, kmgr)
require.NoError(t, err)
- require.NotEmpty(t, tkn)
- kmgr, err := keyManager().getKeyManger(tkn)
+ tkn, err := sessionManager().createSession(profileInfo.User, kmgr, 500*time.Millisecond)
+
require.NoError(t, err)
require.NotEmpty(t, kmgr)
@@ -249,7 +250,7 @@ func TestContentStores(t *testing.T) {
require.Empty(t, sp.config.TagNames)
// open store
- require.NoError(t, contentStore.Open(tkn, &unlockOpts{
+ require.NoError(t, contentStore.Open(kmgr, &unlockOpts{
edvOpts: []edv.RESTProviderOption{
edv.WithFullDocumentsReturnedFromQueries(),
edv.WithBatchEndpointExtension(),
@@ -270,7 +271,7 @@ func TestContentStores(t *testing.T) {
// open store error
sp.ErrOpenStoreHandle = errors.New(sampleContenttErr)
- err := contentStore.Open(token, &unlockOpts{})
+ err := contentStore.Open(keyMgr, &unlockOpts{})
require.Error(t, err)
require.Contains(t, err.Error(), sampleContenttErr)
require.Contains(t, err.Error(), "failed to open store")
@@ -278,7 +279,7 @@ func TestContentStores(t *testing.T) {
// set store config error
sp.ErrOpenStoreHandle = nil
sp.failure = errors.New(sampleContenttErr)
- err = contentStore.Open(token, &unlockOpts{})
+ err = contentStore.Open(keyMgr, &unlockOpts{})
require.Error(t, err)
require.Contains(t, err.Error(), sampleContenttErr)
require.Contains(t, err.Error(), "failed to set store config")
@@ -287,7 +288,7 @@ func TestContentStores(t *testing.T) {
sp.failure = nil
sp.Store.ErrClose = errors.New(sampleContenttErr)
contentStore = newContentStore(sp, &profile{ID: uuid.New().String()})
- require.NoError(t, contentStore.Open(token, &unlockOpts{}))
+ require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
require.True(t, contentStore.Close())
})
@@ -298,7 +299,7 @@ func TestContentStores(t *testing.T) {
contentStore := newContentStore(sp, &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
- require.NoError(t, contentStore.Open(token, &unlockOpts{}))
+ require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
err := contentStore.Save(token, Collection, []byte(sampleContentValid))
require.NoError(t, err)
@@ -318,7 +319,7 @@ func TestContentStores(t *testing.T) {
contentStore := newContentStore(sp, &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
- require.NoError(t, contentStore.Open(token, &unlockOpts{}))
+ require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
err := contentStore.Save(token, Collection, []byte(sampleContentNoID))
require.NoError(t, err)
@@ -330,7 +331,7 @@ func TestContentStores(t *testing.T) {
contentStore := newContentStore(sp, &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
- require.NoError(t, contentStore.Open(token, &unlockOpts{}))
+ require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
err := contentStore.Save(token, DIDResolutionResponse, []byte(didResolutionResult))
require.NoError(t, err)
@@ -376,8 +377,13 @@ func TestContentStores(t *testing.T) {
MasterLockCipher: masterLockCipherText,
}
- tkn, err := keyManager().createKeyManager(profileInfo, mockstorage.NewMockStoreProvider(),
+ kmgr, err := keyManager().createKeyManager(profileInfo, mockstorage.NewMockStoreProvider(),
&unlockOpts{passphrase: samplePassPhrase})
+ require.NotEmpty(t, kmgr)
+ require.NoError(t, err)
+
+ tkn, err := sessionManager().createSession(profileInfo.User, kmgr, 500*time.Millisecond)
+
require.NoError(t, err)
require.NotEmpty(t, tkn)
@@ -444,7 +450,7 @@ func TestContentStores(t *testing.T) {
err = contentStore.Save(token, Credential, []byte(sampleContentValid))
require.True(t, errors.Is(err, ErrWalletLocked))
- require.NoError(t, contentStore.Open(token, &unlockOpts{}))
+ require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
err = contentStore.Save(token, Credential, []byte(sampleContentValid))
require.Error(t, err)
@@ -473,7 +479,7 @@ func TestContentStores(t *testing.T) {
contentStore := newContentStore(sp, &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
- require.NoError(t, contentStore.Open(token, &unlockOpts{}))
+ require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
err := contentStore.Save(token, Collection, []byte(sampleContentValid))
require.NoError(t, err)
@@ -490,7 +496,7 @@ func TestContentStores(t *testing.T) {
contentStore := newContentStore(sp, &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
- require.NoError(t, contentStore.Open(token, &unlockOpts{}))
+ require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
// save
err := contentStore.Save(token, Collection, []byte(sampleContentValid))
@@ -513,7 +519,7 @@ func TestContentStores(t *testing.T) {
require.Empty(t, content)
require.True(t, errors.Is(err, ErrWalletLocked))
- require.NoError(t, contentStore.Open(token, &unlockOpts{}))
+ require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
// get
content, err = contentStore.Get(token, "did:example:123456789abcdefghi", Collection)
@@ -528,7 +534,7 @@ func TestContentStores(t *testing.T) {
contentStore := newContentStore(sp, &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
- require.NoError(t, contentStore.Open(token, &unlockOpts{}))
+ require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
// save
err := contentStore.Save(token, Collection, []byte(sampleContentValid))
@@ -557,7 +563,7 @@ func TestContentStores(t *testing.T) {
contentStore := newContentStore(sp, &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
- require.NoError(t, contentStore.Open(token, &unlockOpts{}))
+ require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
// save
err := contentStore.Save(token, Collection, []byte(sampleContentValid))
@@ -606,9 +612,10 @@ func TestContentStore_GetAll(t *testing.T) {
"description" : "Professional software developer for Acme Corp."
}`
- token := uuid.New().String()
+ keyMgr := &mockkms.KeyManager{}
- require.NoError(t, keyManager().saveKeyManger(uuid.New().String(), token, &mockkms.KeyManager{}, 500*time.Millisecond))
+ token, err := sessionManager().createSession(uuid.New().String(), keyMgr, 500*time.Millisecond)
+ require.NoError(t, err)
t.Run("get all content from store for credential type - success", func(t *testing.T) {
sp := getMockStorageProvider()
@@ -616,7 +623,7 @@ func TestContentStore_GetAll(t *testing.T) {
contentStore := newContentStore(sp, &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
- require.NoError(t, contentStore.Open(token, &unlockOpts{}))
+ require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
// save test data
const count = 5
@@ -656,7 +663,7 @@ func TestContentStore_GetAll(t *testing.T) {
require.True(t, errors.Is(err, ErrWalletLocked))
require.Empty(t, allVcs)
- require.NoError(t, contentStore.Open(token, &unlockOpts{}))
+ require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
require.NoError(t, contentStore.Save(token, Credential, []byte(fmt.Sprintf(vcContent, uuid.New().String()))))
// iterator value error
@@ -671,7 +678,7 @@ func TestContentStore_GetAll(t *testing.T) {
contentStore = newContentStore(sp, &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
- require.NoError(t, contentStore.Open(token, &unlockOpts{}))
+ require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
allVcs, err = contentStore.GetAll(token, Credential)
require.True(t, errors.Is(err, sp.MockStoreProvider.Store.ErrKey))
@@ -682,7 +689,7 @@ func TestContentStore_GetAll(t *testing.T) {
contentStore = newContentStore(sp, &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
- require.NoError(t, contentStore.Open(token, &unlockOpts{}))
+ require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
require.NoError(t, contentStore.Save(token, Credential, []byte(fmt.Sprintf(vcContent, uuid.New().String()))))
@@ -695,7 +702,7 @@ func TestContentStore_GetAll(t *testing.T) {
contentStore = newContentStore(sp, &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
- require.NoError(t, contentStore.Open(token, &unlockOpts{}))
+ require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
allVcs, err = contentStore.GetAll(token, Credential)
require.True(t, errors.Is(err, sp.MockStoreProvider.Store.ErrQuery))
@@ -704,16 +711,17 @@ func TestContentStore_GetAll(t *testing.T) {
}
func TestContentDIDResolver(t *testing.T) {
- token := uuid.New().String()
+ keyMgr := &mockkms.KeyManager{}
- require.NoError(t, keyManager().saveKeyManger(uuid.New().String(), token, &mockkms.KeyManager{}, 500*time.Millisecond))
+ token, err := sessionManager().createSession(uuid.New().String(), keyMgr, 500*time.Millisecond)
+ require.NoError(t, err)
t.Run("create new content store - success", func(t *testing.T) {
sp := getMockStorageProvider()
contentStore := newContentStore(sp, &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
- require.NoError(t, contentStore.Open(token, &unlockOpts{}))
+ require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
// save custom DID
err := contentStore.Save(token, DIDResolutionResponse, testdata.SampleDocResolutionResponse)
@@ -749,7 +757,7 @@ func TestContentDIDResolver(t *testing.T) {
require.Empty(t, didDoc)
// open store
- require.NoError(t, contentStore.Open(token, &unlockOpts{}))
+ require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
// DID not found
didDoc, err = contentVDR.Resolve("did:key:invalid")
@@ -827,16 +835,17 @@ func TestContentStore_Collections(t *testing.T) {
const collectionID = "did:example:acme123456789abcdefghi"
- token := uuid.New().String()
+ keyMgr := &mockkms.KeyManager{}
- require.NoError(t, keyManager().saveKeyManger(uuid.New().String(), token, &mockkms.KeyManager{}, 500*time.Millisecond))
+ token, err := sessionManager().createSession(uuid.New().String(), keyMgr, 500*time.Millisecond)
+ require.NoError(t, err)
t.Run("contents by collection - success", func(t *testing.T) {
sp := getMockStorageProvider()
contentStore := newContentStore(sp, &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
- require.NoError(t, contentStore.Open(token, &unlockOpts{}))
+ require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
// save a collection
require.NoError(t, contentStore.Save(token, Collection, []byte(orgCollection)))
@@ -902,7 +911,7 @@ func TestContentStore_Collections(t *testing.T) {
contentStore := newContentStore(sp, &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
- require.NoError(t, contentStore.Open(token, &unlockOpts{}))
+ require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
err := contentStore.Save(token,
DIDResolutionResponse, []byte(didResolutionResult), AddByCollection(collectionID+"invalid"))
@@ -924,7 +933,7 @@ func TestContentStore_Collections(t *testing.T) {
contentStore = newContentStore(sp, &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
- require.NoError(t, contentStore.Open(token, &unlockOpts{}))
+ require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
allVcs, err := contentStore.GetAllByCollection(token, collectionID, Credential)
require.True(t, errors.Is(err, sp.MockStoreProvider.Store.ErrGet))
@@ -935,7 +944,7 @@ func TestContentStore_Collections(t *testing.T) {
contentStore = newContentStore(sp, &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
- require.NoError(t, contentStore.Open(token, &unlockOpts{}))
+ require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
allVcs, err = contentStore.GetAllByCollection(token, collectionID, Credential)
require.True(t, errors.Is(err, sp.MockStoreProvider.Store.ErrValue))
@@ -946,7 +955,7 @@ func TestContentStore_Collections(t *testing.T) {
contentStore = newContentStore(sp, &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
- require.NoError(t, contentStore.Open(token, &unlockOpts{}))
+ require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
allVcs, err = contentStore.GetAllByCollection(token, collectionID, Credential)
require.True(t, errors.Is(err, sp.MockStoreProvider.Store.ErrKey))
@@ -957,7 +966,7 @@ func TestContentStore_Collections(t *testing.T) {
contentStore = newContentStore(sp, &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
- require.NoError(t, contentStore.Open(token, &unlockOpts{}))
+ require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
allVcs, err = contentStore.GetAllByCollection(token, collectionID, Credential)
require.True(t, errors.Is(err, sp.MockStoreProvider.Store.ErrNext))
@@ -968,7 +977,7 @@ func TestContentStore_Collections(t *testing.T) {
contentStore = newContentStore(sp, &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
- require.NoError(t, contentStore.Open(token, &unlockOpts{}))
+ require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
allVcs, err = contentStore.GetAllByCollection(token, collectionID, Credential)
require.True(t, errors.Is(err, sp.MockStoreProvider.Store.ErrQuery))
diff --git a/pkg/wallet/kmsclient.go b/pkg/wallet/kmsclient.go
index ae057febf..2244f5a8e 100644
--- a/pkg/wallet/kmsclient.go
+++ b/pkg/wallet/kmsclient.go
@@ -15,12 +15,10 @@ import (
"net/http"
"strings"
"sync"
- "time"
"github.com/bluele/gcache"
"github.com/btcsuite/btcutil/base58"
"github.com/google/tink/go/subtle/random"
- "github.com/google/uuid"
"github.com/hyperledger/aries-framework-go/pkg/crypto"
"github.com/hyperledger/aries-framework-go/pkg/crypto/primitive/bbs12381g2pub"
@@ -38,9 +36,6 @@ const (
// LocalKeyURIPrefix for locally stored keys.
localKeyURIPrefix = "local-lock://"
- // default cache expiry time.
- defaultCacheExpiry = 10 * time.Minute
-
// number of sections in verification method.
vmSectionCount = 2
)
@@ -65,11 +60,8 @@ var (
// ErrAlreadyUnlocked error when key manager is already created for a given user.
ErrAlreadyUnlocked = errors.New("wallet already unlocked")
- // WalletLocked when key manager operation is attempted without unlocking wallet.
+ // ErrWalletLocked when key manager operation is attempted without unlocking wallet.
ErrWalletLocked = errors.New("wallet locked")
-
- // ErrInvalidAuthToken when auth token provided to wallet is unable to unlock key manager.
- ErrInvalidAuthToken = errors.New("invalid auth token")
)
// walletKMSInstance is key manager store singleton - access only via keyManager()
@@ -96,15 +88,9 @@ type walletKeyManager struct {
}
func (k *walletKeyManager) createKeyManager(profileInfo *profile,
- storeProvider storage.Provider, opts *unlockOpts) (string, error) {
+ storeProvider storage.Provider, opts *unlockOpts) (kms.KeyManager, error) {
if profileInfo.MasterLockCipher == "" && profileInfo.KeyServerURL == "" {
- return "", fmt.Errorf("invalid wallet profile")
- }
-
- // get user from cache if token already exists
- token, _ := k.getKeyMangerToken(profileInfo.User) //nolint: errcheck
- if token != "" {
- return "", ErrAlreadyUnlocked
+ return nil, fmt.Errorf("invalid wallet profile")
}
var err error
@@ -117,64 +103,14 @@ func (k *walletKeyManager) createKeyManager(profileInfo *profile,
keyManager, err = createLocalKeyManager(profileInfo.User, opts.passphrase,
profileInfo.MasterLockCipher, opts.secretLockSvc, storeProvider)
if err != nil {
- return "", fmt.Errorf("failed to create local key manager: %w", err)
+ return nil, fmt.Errorf("failed to create local key manager: %w", err)
}
} else {
// remote kms
keyManager = createRemoteKeyManager(opts, profileInfo.KeyServerURL)
}
- // generate token
- token = uuid.New().String()
-
- // save key manager
- err = k.saveKeyManger(profileInfo.User, token, keyManager, opts.tokenExpiry)
- if err != nil {
- return "", fmt.Errorf("failed to persist local key manager: %w", err)
- }
-
- return token, nil
-}
-
-// TODO refresh expiry on each access.
-func (k *walletKeyManager) saveKeyManger(user, key string, manager kms.KeyManager, expiration time.Duration) error {
- if expiration == 0 {
- expiration = defaultCacheExpiry
- }
-
- err := k.gstore.SetWithExpire(user, key, expiration)
- if err != nil {
- return err
- }
-
- return k.gstore.SetWithExpire(key, manager, expiration)
-}
-
-func (k *walletKeyManager) getKeyManger(key string) (kms.KeyManager, error) {
- val, err := k.gstore.Get(key)
- if err != nil {
- return nil, err
- }
-
- return val.(kms.KeyManager), nil
-}
-
-func (k *walletKeyManager) getKeyMangerToken(user string) (string, error) {
- val, err := k.gstore.Get(user)
- if err != nil {
- return "", err
- }
-
- return val.(string), nil
-}
-
-func (k *walletKeyManager) removeKeyManager(user string) bool {
- token, _ := k.getKeyMangerToken(user) //nolint: errcheck
- if token != "" {
- return k.gstore.Remove(token) && k.gstore.Remove(user)
- }
-
- return false
+ return keyManager, nil
}
// createMasterLock creates master lock from secret lock service provided.
@@ -253,15 +189,17 @@ type kmsSigner struct {
}
func newKMSSigner(authToken string, c crypto.Crypto, opts *ProofOptions) (*kmsSigner, error) {
- keyManager, err := keyManager().getKeyManger(authToken)
+ session, err := sessionManager().getSession(authToken)
if err != nil {
- if errors.Is(err, gcache.KeyNotFoundError) {
+ if errors.Is(err, ErrInvalidAuthToken) {
return nil, ErrWalletLocked
}
- return nil, fmt.Errorf("failed to get key manager: %w", err)
+ return nil, fmt.Errorf("failed to get session: %w", err)
}
+ keyManager := session.KeyManager
+
vmSplit := strings.Split(opts.VerificationMethod, "#")
if len(vmSplit) != vmSectionCount {
@@ -305,15 +243,17 @@ func (s *kmsSigner) Sign(data []byte) ([]byte, error) {
// importKeyJWK imports private key jwk found in key contents,
// supported curve types - Ed25519, P-256, BLS12381G2.
func importKeyJWK(auth string, key *keyContent) error {
- keyManager, err := keyManager().getKeyManger(auth)
+ session, err := sessionManager().getSession(auth)
if err != nil {
- if errors.Is(err, gcache.KeyNotFoundError) {
+ if errors.Is(err, ErrInvalidAuthToken) {
return ErrWalletLocked
}
- return fmt.Errorf("failed to get key manager: %w", err)
+ return fmt.Errorf("failed to get session: %w", err)
}
+ keyManager := session.KeyManager
+
var j jwk.JWK
if e := j.UnmarshalJSON(key.PrivateKeyJwk); e != nil {
return fmt.Errorf("failed to unmarshal jwk : %w", e)
@@ -335,15 +275,17 @@ func importKeyJWK(auth string, key *keyContent) error {
// importKeyBase58 imports private key base58 found in key contents,
// supported types - Ed25519Signature2018, Bls12381G1Key2020.
func importKeyBase58(auth string, key *keyContent) error {
- keyManager, err := keyManager().getKeyManger(auth)
+ session, err := sessionManager().getSession(auth)
if err != nil {
- if errors.Is(err, gcache.KeyNotFoundError) {
+ if errors.Is(err, ErrInvalidAuthToken) {
return ErrWalletLocked
}
- return fmt.Errorf("failed to get key manager: %w", err)
+ return fmt.Errorf("failed to get session: %w", err)
}
+ keyManager := session.KeyManager
+
switch strings.ToLower(key.KeyType) {
case Ed25519VerificationKey2018:
edPriv := ed25519.PrivateKey(base58.Decode(key.PrivateKeyBase58))
diff --git a/pkg/wallet/kmsclient_test.go b/pkg/wallet/kmsclient_test.go
index f987612a1..d341457aa 100644
--- a/pkg/wallet/kmsclient_test.go
+++ b/pkg/wallet/kmsclient_test.go
@@ -25,7 +25,6 @@ import (
const (
samplePassPhrase = "fakepassphrase"
sampleRemoteKMSAuth = "sample-auth-token"
- keyNotFoundErr = "Key not found."
sampleKeyMgrErr = "sample-keymgr-err"
)
@@ -51,22 +50,10 @@ func TestKeyManager(t *testing.T) {
MasterLockCipher: masterLockCipherText,
}
- tkn, err := keyManager().createKeyManager(profileInfo, mockstorage.NewMockStoreProvider(),
+ kmgr, err := keyManager().createKeyManager(profileInfo, mockstorage.NewMockStoreProvider(),
&unlockOpts{passphrase: samplePassPhrase})
require.NoError(t, err)
- require.NotEmpty(t, tkn)
-
- // get key manager
- kmgr, err := keyManager().getKeyManger(tkn)
- require.NoError(t, err)
require.NotEmpty(t, kmgr)
-
- // try to create again before expiry
- tkn, err = keyManager().createKeyManager(profileInfo, mockstorage.NewMockStoreProvider(),
- &unlockOpts{passphrase: samplePassPhrase})
- require.Error(t, err)
- require.Equal(t, err, ErrAlreadyUnlocked)
- require.Empty(t, tkn)
})
t.Run("create key manager for localkms - with secret lock service", func(t *testing.T) {
@@ -83,22 +70,10 @@ func TestKeyManager(t *testing.T) {
MasterLockCipher: masterLockCipherText,
}
- tkn, err := keyManager().createKeyManager(profileInfo, mockstorage.NewMockStoreProvider(),
+ kmgr, err := keyManager().createKeyManager(profileInfo, mockstorage.NewMockStoreProvider(),
&unlockOpts{secretLockSvc: masterLock})
require.NoError(t, err)
- require.NotEmpty(t, tkn)
-
- // get key manager
- kmgr, err := keyManager().getKeyManger(tkn)
- require.NoError(t, err)
require.NotEmpty(t, kmgr)
-
- // try to create again before expiry
- tkn, err = keyManager().createKeyManager(profileInfo, mockstorage.NewMockStoreProvider(),
- &unlockOpts{secretLockSvc: masterLock})
- require.Error(t, err)
- require.Equal(t, err, ErrAlreadyUnlocked)
- require.Empty(t, tkn)
})
t.Run("create key manager for localkms - passphrase missmatch", func(t *testing.T) {
@@ -116,17 +91,11 @@ func TestKeyManager(t *testing.T) {
}
// use wrong passphrase
- tkn, err := keyManager().createKeyManager(profileInfo, mockstorage.NewMockStoreProvider(),
+ kmgr, err := keyManager().createKeyManager(profileInfo, mockstorage.NewMockStoreProvider(),
&unlockOpts{passphrase: samplePassPhrase + "wrong"})
- require.Empty(t, tkn)
- require.Error(t, err)
- require.Contains(t, err.Error(), "message authentication failed")
-
- // get key manager
- kmgr, err := keyManager().getKeyManger(tkn)
require.Empty(t, kmgr)
require.Error(t, err)
- require.EqualError(t, err, keyNotFoundErr)
+ require.Contains(t, err.Error(), "message authentication failed")
})
t.Run("create key manager for localkms - secret lock service missmatch", func(t *testing.T) {
@@ -147,17 +116,11 @@ func TestKeyManager(t *testing.T) {
masterLockBad, err := pbkdf2.NewMasterLock(samplePassPhrase+"wrong", sha256.New, 0, nil)
require.NoError(t, err)
- tkn, err := keyManager().createKeyManager(profileInfo, mockstorage.NewMockStoreProvider(),
+ kmgr, err := keyManager().createKeyManager(profileInfo, mockstorage.NewMockStoreProvider(),
&unlockOpts{secretLockSvc: masterLockBad})
- require.Empty(t, tkn)
- require.Error(t, err)
- require.Contains(t, err.Error(), "message authentication failed")
-
- // get key manager
- kmgr, err := keyManager().getKeyManger(tkn)
require.Empty(t, kmgr)
require.Error(t, err)
- require.EqualError(t, err, keyNotFoundErr)
+ require.Contains(t, err.Error(), "message authentication failed")
})
t.Run("create key manager for remotekms", func(t *testing.T) {
@@ -167,25 +130,13 @@ func TestKeyManager(t *testing.T) {
KeyServerURL: sampleKeyServerURL,
}
- tkn, err := keyManager().createKeyManager(profileInfo, mockstorage.NewMockStoreProvider(),
+ kmgr, err := keyManager().createKeyManager(profileInfo, mockstorage.NewMockStoreProvider(),
&unlockOpts{authToken: sampleRemoteKMSAuth})
require.NoError(t, err)
- require.NotEmpty(t, tkn)
-
- // get key manager
- kmgr, err := keyManager().getKeyManger(tkn)
- require.NoError(t, err)
require.NotEmpty(t, kmgr)
_, _, err = kmgr.Create(kmsapi.ED25519Type)
require.Error(t, err)
-
- // try to create again before expiry
- tkn, err = keyManager().createKeyManager(profileInfo, mockstorage.NewMockStoreProvider(),
- &unlockOpts{authToken: sampleRemoteKMSAuth})
- require.Error(t, err)
- require.Equal(t, err, ErrAlreadyUnlocked)
- require.Empty(t, tkn)
})
t.Run("create key manager for failure - invalid profile", func(t *testing.T) {
@@ -193,63 +144,11 @@ func TestKeyManager(t *testing.T) {
User: uuid.New().String(),
}
- tkn, err := keyManager().createKeyManager(profileInfo, mockstorage.NewMockStoreProvider(),
- &unlockOpts{authToken: sampleRemoteKMSAuth})
- require.Empty(t, tkn)
- require.Error(t, err)
- require.Contains(t, err.Error(), "invalid wallet profile")
-
- // get key manager
- kmgr, err := keyManager().getKeyManger(tkn)
- require.Empty(t, kmgr)
- require.Error(t, err)
- require.EqualError(t, err, keyNotFoundErr)
- })
-
- t.Run("test remove key manager", func(t *testing.T) {
- sampleUser := uuid.New().String()
- profileInfo := &profile{
- User: sampleUser,
- KeyServerURL: sampleKeyServerURL,
- }
-
- tkn, err := keyManager().createKeyManager(profileInfo, mockstorage.NewMockStoreProvider(),
- &unlockOpts{authToken: sampleRemoteKMSAuth})
- require.NoError(t, err)
- require.NotEmpty(t, tkn)
-
- // get key manager
- kmgr, err := keyManager().getKeyManger(tkn)
- require.NoError(t, err)
- require.NotEmpty(t, kmgr)
-
- // try to create again before expiry
- tkn, err = keyManager().createKeyManager(profileInfo, mockstorage.NewMockStoreProvider(),
+ kmgr, err := keyManager().createKeyManager(profileInfo, mockstorage.NewMockStoreProvider(),
&unlockOpts{authToken: sampleRemoteKMSAuth})
- require.Error(t, err)
- require.Equal(t, err, ErrAlreadyUnlocked)
- require.Empty(t, tkn)
-
- // remove key manager
- require.True(t, keyManager().removeKeyManager(profileInfo.User))
- require.False(t, keyManager().removeKeyManager(profileInfo.User))
-
- // try to get key manager
- kmgr, err = keyManager().getKeyManger(tkn)
require.Empty(t, kmgr)
require.Error(t, err)
- require.EqualError(t, err, keyNotFoundErr)
-
- // try again to create
- tkn, err = keyManager().createKeyManager(profileInfo, mockstorage.NewMockStoreProvider(),
- &unlockOpts{authToken: sampleRemoteKMSAuth})
- require.NoError(t, err)
- require.NotEmpty(t, tkn)
-
- // get key manager
- kmgr, err = keyManager().getKeyManger(tkn)
- require.NoError(t, err)
- require.NotEmpty(t, kmgr)
+ require.Contains(t, err.Error(), "invalid wallet profile")
})
}
@@ -267,10 +166,13 @@ func TestImportKeyJWK(t *testing.T) {
MasterLockCipher: masterLockCipherText,
}
- tkn, err := keyManager().createKeyManager(profileInfo, mockstorage.NewMockStoreProvider(),
+ kmgr, err := keyManager().createKeyManager(profileInfo, mockstorage.NewMockStoreProvider(),
&unlockOpts{passphrase: samplePassPhrase})
require.NoError(t, err)
- require.NotEmpty(t, tkn)
+ require.NotEmpty(t, kmgr)
+
+ tkn, err := sessionManager().createSession(uuid.New().String(), kmgr, 0)
+ require.NoError(t, err)
t.Run("test successful jwk key imports", func(t *testing.T) {
tests := []struct {
@@ -372,9 +274,6 @@ func TestImportKeyJWK(t *testing.T) {
err := importKeyJWK(tkn, &keyContent{PrivateKeyJwk: tc.sampleJWK, ID: tc.ID})
require.NoError(t, err)
- kmgr, err := keyManager().getKeyManger(tkn)
- require.NoError(t, err)
-
handle, err := kmgr.Get(getKID(tc.ID))
require.NoError(t, err)
require.NotEmpty(t, handle)
@@ -451,9 +350,13 @@ func TestImportKeyBase58(t *testing.T) {
MasterLockCipher: masterLockCipherText,
}
- tkn, e := keyManager().createKeyManager(profileInfo, mockstorage.NewMockStoreProvider(),
+ kmgr, e := keyManager().createKeyManager(profileInfo, mockstorage.NewMockStoreProvider(),
&unlockOpts{passphrase: samplePassPhrase})
require.NoError(t, e)
+ require.NotEmpty(t, kmgr)
+
+ tkn, e := sessionManager().createSession(uuid.New().String(), kmgr, 0)
+ require.NoError(t, e)
require.NotEmpty(t, tkn)
t.Run("test successful base58 key imports", func(t *testing.T) {
@@ -516,9 +419,6 @@ func TestImportKeyBase58(t *testing.T) {
})
require.NoError(t, err)
- kmgr, err := keyManager().getKeyManger(tkn)
- require.NoError(t, err)
-
handle, err := kmgr.Get(getKID(tc.ID))
require.NoError(t, err)
require.NotEmpty(t, handle)
@@ -553,15 +453,16 @@ func TestImportKeyBase58(t *testing.T) {
})
t.Run("test import errors", func(t *testing.T) {
- mockToken := "mock-token"
-
sampleErr := errors.New(sampleKeyMgrErr)
- wkmgr := keyManager()
- err := wkmgr.saveKeyManger(uuid.New().String(), mockToken,
+
+ tkn, err := sessionManager().createSession(uuid.New().String(),
&mockkms.KeyManager{ImportPrivateKeyErr: sampleErr}, 0)
require.NoError(t, err)
+ require.NotEmpty(t, tkn)
+
+ require.NoError(t, err)
- err = importKeyBase58(mockToken, &keyContent{
+ err = importKeyBase58(tkn, &keyContent{
ID: "did:example:123#z6MkiEh8RQL83nkPo8ehDeE5",
PrivateKeyBase58: "zJRjGFZydU5DBdS2p5qbiUzDFAxbXTkjiDuGPksMBbY5TNyEsGfK4a4WGKjBCh1zeNryeuKtPotp8W1ESnwP71y",
KeyType: "Ed25519VerificationKey2018",
@@ -569,7 +470,7 @@ func TestImportKeyBase58(t *testing.T) {
require.Error(t, err)
require.True(t, errors.Is(err, sampleErr))
- err = importKeyBase58(mockToken, &keyContent{
+ err = importKeyBase58(tkn, &keyContent{
ID: "did:example:123#z6MkiEh8RQL83nkPo8ehDeE5",
PrivateKeyBase58: "6gsgGpdx7p1nYoKJ4b5fKt1xEomWdnemg9nJFX6mqNCh",
KeyType: "Bls12381G1Key2020",
@@ -580,9 +481,9 @@ func TestImportKeyBase58(t *testing.T) {
}
func TestKMSSigner(t *testing.T) {
- token := uuid.New().String()
-
- require.NoError(t, keyManager().saveKeyManger(uuid.New().String(), token, &mockkms.KeyManager{}, 500*time.Millisecond))
+ token, err := sessionManager().createSession(uuid.New().String(),
+ &mockkms.KeyManager{}, 500*time.Millisecond)
+ require.NoError(t, err)
t.Run("test kms signer errors", func(t *testing.T) {
// invalid auth
diff --git a/pkg/wallet/profile_test.go b/pkg/wallet/profile_test.go
index dee7e370e..e1edb197e 100644
--- a/pkg/wallet/profile_test.go
+++ b/pkg/wallet/profile_test.go
@@ -10,9 +10,7 @@ import (
"errors"
"fmt"
"testing"
- "time"
- "github.com/google/uuid"
"github.com/stretchr/testify/require"
mockkms "github.com/hyperledger/aries-framework-go/pkg/mock/kms"
@@ -128,11 +126,7 @@ func TestCreateNewProfile(t *testing.T) {
},
}
- token := uuid.New().String()
kid := "sample-kid"
- kms := &mockkms.KeyManager{CreateKeyID: kid}
-
- require.NoError(t, keyManager().saveKeyManger(uuid.New().String(), token, kms, 500*time.Millisecond))
// setup edv keys
err := sampleProfile.setupEDVEncryptionKey(&mockkms.KeyManager{CreateKeyID: kid})
diff --git a/pkg/wallet/session.go b/pkg/wallet/session.go
new file mode 100644
index 000000000..b8424f7c2
--- /dev/null
+++ b/pkg/wallet/session.go
@@ -0,0 +1,144 @@
+/*
+Copyright SecureKey Technologies Inc. All Rights Reserved.
+
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package wallet
+
+import (
+ "crypto/rand"
+ "encoding/hex"
+ "fmt"
+ "sync"
+ "time"
+
+ "github.com/bluele/gcache"
+ "github.com/pkg/errors"
+
+ "github.com/hyperledger/aries-framework-go/pkg/kms"
+)
+
+// ErrInvalidAuthToken when auth token provided to wallet is unable to unlock key manager.
+var ErrInvalidAuthToken = errors.New("invalid auth token")
+
+const (
+ // default cache expiry time.
+ defaultCacheExpiry = 10 * time.Minute
+ sessionTokenSize = 32
+)
+
+// Session represent a session object created when user unlock wallet.
+type Session struct {
+ KeyManager kms.KeyManager
+ sessionExpiry time.Duration
+ user string
+}
+
+// sessionManagerInstance is key manager store singleton - access only via sessionManager()
+//nolint:gochecknoglobals
+var (
+ sessionManagerInstance *walletSessionManager
+ sessionManagerStoreOnce sync.Once
+)
+
+func sessionManager() *walletSessionManager {
+ sessionManagerStoreOnce.Do(func() {
+ sessionManagerInstance = &walletSessionManager{
+ gstore: gcache.New(0).Build(),
+ }
+ })
+
+ return sessionManagerInstance
+}
+
+type walletSessionManager struct {
+ gstore gcache.Cache
+ mu sync.Mutex
+}
+
+func (s *walletSessionManager) createSession(userID string, keyManager kms.KeyManager,
+ sessionExpiry time.Duration) (string, error) {
+ if sessionExpiry == 0 {
+ sessionExpiry = defaultCacheExpiry
+ }
+
+ session := &Session{
+ KeyManager: keyManager,
+ sessionExpiry: sessionExpiry,
+ user: userID,
+ }
+
+ s.mu.Lock()
+ defer s.mu.Unlock()
+
+ for _, sess := range s.gstore.GetALL(true) {
+ if sess.(*Session).user == userID {
+ return "", ErrAlreadyUnlocked
+ }
+ }
+
+ for {
+ token, err := s.generateToken()
+ if err != nil {
+ return "", err
+ }
+
+ if !s.gstore.Has(token) {
+ err = s.gstore.SetWithExpire(token, session, sessionExpiry)
+
+ if err != nil {
+ return "", fmt.Errorf("set with expire failed: %w", err)
+ }
+
+ return token, nil
+ }
+ }
+}
+
+func (s *walletSessionManager) getSession(authToken string) (*Session, error) {
+ sess, err := s.gstore.Get(authToken)
+ if err != nil {
+ if errors.Is(err, gcache.KeyNotFoundError) {
+ return nil, ErrInvalidAuthToken
+ }
+
+ return nil, fmt.Errorf("failed to get session object: %w", err)
+ }
+
+ session, ok := sess.(*Session)
+ if !ok {
+ return nil, fmt.Errorf("failed to cast session object: expects Session, gets %T", sess)
+ }
+
+ err = s.gstore.SetWithExpire(authToken, session, session.sessionExpiry)
+ if err != nil {
+ return nil, fmt.Errorf("set with expire failed: %w", err)
+ }
+
+ return session, nil
+}
+
+func (s *walletSessionManager) closeSession(userID string) bool {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+
+ for token, sess := range s.gstore.GetALL(true) {
+ if sess.(*Session).user == userID {
+ return s.gstore.Remove(token)
+ }
+ }
+
+ return false
+}
+
+func (s *walletSessionManager) generateToken() (string, error) {
+ tokenBytes := make([]byte, sessionTokenSize)
+
+ _, err := rand.Read(tokenBytes)
+ if err != nil {
+ return "", fmt.Errorf("failed to create random sessoin token: %w", err)
+ }
+
+ return hex.EncodeToString(tokenBytes), nil
+}
diff --git a/pkg/wallet/sesson_test.go b/pkg/wallet/sesson_test.go
new file mode 100644
index 000000000..1fee499b8
--- /dev/null
+++ b/pkg/wallet/sesson_test.go
@@ -0,0 +1,91 @@
+/*
+Copyright SecureKey Technologies Inc. All Rights Reserved.
+
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package wallet
+
+import (
+ "testing"
+
+ "github.com/google/uuid"
+ "github.com/stretchr/testify/require"
+
+ mockkms "github.com/hyperledger/aries-framework-go/pkg/mock/kms"
+)
+
+func TestSessionManager_CreateSession(t *testing.T) {
+ t.Run("successfully create session", func(t *testing.T) {
+ token, err := sessionManager().createSession(uuid.New().String(), &mockkms.KeyManager{}, 0)
+
+ require.NoError(t, err)
+ require.NotEmpty(t, token)
+ })
+
+ t.Run("fail to create created session - wallet already unlocked", func(t *testing.T) {
+ user := uuid.New().String()
+
+ token, err := sessionManager().createSession(user, &mockkms.KeyManager{}, 0)
+
+ require.NoError(t, err)
+ require.NotEmpty(t, token)
+
+ _, err = sessionManager().createSession(user, &mockkms.KeyManager{}, 0)
+ require.EqualError(t, err, "wallet already unlocked")
+ })
+}
+
+func TestSessionManager_GetSession(t *testing.T) {
+ t.Run("successfully get session", func(t *testing.T) {
+ token, err := sessionManager().createSession(uuid.New().String(), &mockkms.KeyManager{}, 0)
+
+ require.NoError(t, err)
+ require.NotEmpty(t, token)
+
+ sess, err := sessionManager().getSession(token)
+
+ require.NoError(t, err)
+ require.NotEmpty(t, sess)
+ })
+
+ t.Run("fail to create created session - wallet already unlocked", func(t *testing.T) {
+ token := "token with invalid data"
+
+ err := sessionManager().gstore.Set(token, "invalid sess object")
+
+ require.NoError(t, err)
+
+ _, err = sessionManager().getSession(token)
+
+ require.EqualError(t, err, "failed to cast session object: expects Session, gets string")
+
+ sessionManager().gstore.Remove(token)
+ })
+}
+
+func TestSessionManager_CloseSession(t *testing.T) {
+ t.Run("successfully close session", func(t *testing.T) {
+ user := uuid.New().String()
+
+ token, err := sessionManager().createSession(user, &mockkms.KeyManager{}, 0)
+
+ require.NoError(t, err)
+ require.NotEmpty(t, token)
+
+ sess, err := sessionManager().getSession(token)
+
+ require.NoError(t, err)
+ require.NotEmpty(t, sess)
+
+ closed := sessionManager().closeSession(user)
+ require.True(t, closed)
+
+ closed = sessionManager().closeSession(user)
+ require.False(t, closed)
+
+ _, err = sessionManager().getSession(token)
+
+ require.EqualError(t, err, "invalid auth token")
+ })
+}
diff --git a/pkg/wallet/storage.go b/pkg/wallet/storage.go
index 2513e0f9b..ff6897e49 100644
--- a/pkg/wallet/storage.go
+++ b/pkg/wallet/storage.go
@@ -13,7 +13,6 @@ import (
"fmt"
"net/http"
- "github.com/bluele/gcache"
"github.com/hyperledger/aries-framework-go/pkg/crypto/webkms"
"github.com/hyperledger/aries-framework-go/component/storage/edv"
@@ -41,12 +40,12 @@ func newWalletStorageProvider(profile *profile, provider storage.Provider) *stor
// OpenStore opens and returns store and sets store config to provider.
// if wallet profile has EDV settings then auth provided will be used to initialize edv storage provider.
-func (s *storageProvider) OpenStore(auth string, opts *unlockOpts, config storage.StoreConfiguration) (storage.Store, error) {
+func (s *storageProvider) OpenStore(keyMgr kms.KeyManager, opts *unlockOpts, config storage.StoreConfiguration) (storage.Store, error) {
var provider storage.Provider
var err error
if s.profile.EDVConf != nil {
- provider, err = createEDVStorageProvider(auth, s.profile, opts)
+ provider, err = createEDVStorageProvider(keyMgr, s.profile, opts)
if err != nil {
return nil, err
}
@@ -74,20 +73,12 @@ func (s *storageProvider) OpenStore(auth string, opts *unlockOpts, config storag
// TODO (#2815): find a way to allow EDV to be used without importing the edv package, since it causes the main Aries
// module to depend on edv
-func createEDVStorageProvider(auth string, profile *profile, opts *unlockOpts) (storage.Provider, error) {
+func createEDVStorageProvider(keyMgr kms.KeyManager, profile *profile, opts *unlockOpts) (storage.Provider, error) {
if profile.EDVConf.EncryptionKeyID == "" || profile.EDVConf.MACKeyID == "" {
return nil, errors.New("invalid EDV configuration found in wallet profile, key IDs for encryption and MAC operations are missing") //nolint: lll
}
- // get key manager
- keyMgr, err := keyManager().getKeyManger(auth)
- if err != nil {
- if errors.Is(err, gcache.KeyNotFoundError) {
- return nil, ErrWalletLocked
- }
-
- return nil, err
- }
+ var err error
// get crypto
var cryptoImpl crypto.Crypto
diff --git a/pkg/wallet/storage_test.go b/pkg/wallet/storage_test.go
index 6415c4862..4328a005a 100644
--- a/pkg/wallet/storage_test.go
+++ b/pkg/wallet/storage_test.go
@@ -33,8 +33,13 @@ func TestStorageProvider_OpenStore(t *testing.T) {
MasterLockCipher: masterLockCipherText,
}
- token, err := keyManager().createKeyManager(profileInfo, getMockStorageProvider(),
+ kmgr, err := keyManager().createKeyManager(profileInfo, getMockStorageProvider(),
&unlockOpts{passphrase: samplePassPhrase})
+ require.NoError(t, err)
+ require.NotEmpty(t, kmgr)
+
+ token, err := sessionManager().createSession(uuid.New().String(), kmgr, 0)
+
require.NoError(t, err)
require.NotEmpty(t, token)
@@ -43,9 +48,10 @@ func TestStorageProvider_OpenStore(t *testing.T) {
sampleProfile := &profile{ID: uuid.New().String(), User: uuid.New().String()}
wsp := newWalletStorageProvider(sampleProfile, sp)
- store, err := wsp.OpenStore(token, &unlockOpts{},
+ store, e := wsp.OpenStore(kmgr, &unlockOpts{},
storage.StoreConfiguration{TagNames: []string{Credential.Name()}})
- require.NoError(t, err)
+
+ require.NoError(t, e)
require.NotEmpty(t, store)
require.Len(t, sp.config.TagNames, 1)
})
@@ -60,10 +66,6 @@ func TestStorageProvider_OpenStore(t *testing.T) {
KeyServerURL: sampleKeyServerURL,
}
- kmgr, err := keyManager().getKeyManger(token)
- require.NoError(t, err)
- require.NotEmpty(t, kmgr)
-
err = sampleProfile.setupEDVEncryptionKey(kmgr)
require.NoError(t, err)
@@ -72,13 +74,13 @@ func TestStorageProvider_OpenStore(t *testing.T) {
wsp := newWalletStorageProvider(sampleProfile, nil)
- store, err := wsp.OpenStore(token, &unlockOpts{},
+ store, err := wsp.OpenStore(kmgr, &unlockOpts{},
storage.StoreConfiguration{TagNames: []string{Credential.Name()}})
require.NoError(t, err)
require.NotEmpty(t, store)
// with edv opts
- store, err = wsp.OpenStore(token, &unlockOpts{
+ store, err = wsp.OpenStore(kmgr, &unlockOpts{
edvOpts: []edv.RESTProviderOption{
edv.WithFullDocumentsReturnedFromQueries(),
edv.WithBatchEndpointExtension(),
@@ -88,7 +90,7 @@ func TestStorageProvider_OpenStore(t *testing.T) {
require.NotEmpty(t, store)
// no edv opts
- store, err = wsp.OpenStore(token, &unlockOpts{},
+ store, err = wsp.OpenStore(kmgr, &unlockOpts{},
storage.StoreConfiguration{TagNames: []string{Credential.Name()}})
require.NoError(t, err)
require.NotEmpty(t, store)
@@ -105,16 +107,12 @@ func TestStorageProvider_OpenStore(t *testing.T) {
// invalid settings
wsp := newWalletStorageProvider(sampleProfile, nil)
- store, err := wsp.OpenStore(token, &unlockOpts{},
+ store, err := wsp.OpenStore(kmgr, &unlockOpts{},
storage.StoreConfiguration{TagNames: []string{Credential.Name()}})
require.Error(t, err)
require.Contains(t, err.Error(), "invalid EDV configuration found in wallet profile")
require.Empty(t, store)
- kmgr, err := keyManager().getKeyManger(token)
- require.NoError(t, err)
- require.NotEmpty(t, kmgr)
-
err = sampleProfile.setupEDVEncryptionKey(kmgr)
require.NoError(t, err)
@@ -123,16 +121,9 @@ func TestStorageProvider_OpenStore(t *testing.T) {
wsp = newWalletStorageProvider(sampleProfile, nil)
- // invalid auth
- store, err = wsp.OpenStore(token+".", &unlockOpts{},
- storage.StoreConfiguration{TagNames: []string{Credential.Name()}})
- require.Error(t, err)
- require.True(t, errors.Is(err, ErrWalletLocked))
- require.Empty(t, store)
-
// incorrect mac key ID
wsp.profile.EDVConf.MACKeyID += "x"
- store, err = wsp.OpenStore(token, &unlockOpts{},
+ store, err = wsp.OpenStore(kmgr, &unlockOpts{},
storage.StoreConfiguration{TagNames: []string{Credential.Name()}})
require.Error(t, err)
require.Contains(t, err.Error(), "failed to create mac crypto")
@@ -140,7 +131,7 @@ func TestStorageProvider_OpenStore(t *testing.T) {
// incorrect encryption key ID
wsp.profile.EDVConf.EncryptionKeyID += "x"
- store, err = wsp.OpenStore(token, &unlockOpts{},
+ store, err = wsp.OpenStore(kmgr, &unlockOpts{},
storage.StoreConfiguration{TagNames: []string{Credential.Name()}})
require.Error(t, err)
require.Contains(t, err.Error(), "failed to create JWE encrypter")
@@ -162,7 +153,7 @@ func TestStorageProvider_OpenStore(t *testing.T) {
sp.failure = errors.New(sampleWalletErr)
sp.Store.ErrClose = errors.New(sampleWalletErr)
- store, err := wsp.OpenStore(token, &unlockOpts{},
+ store, err := wsp.OpenStore(kmgr, &unlockOpts{},
storage.StoreConfiguration{TagNames: []string{Credential.Name()}})
require.Error(t, err)
require.Empty(t, store)
diff --git a/pkg/wallet/wallet.go b/pkg/wallet/wallet.go
index 5f09d9ada..ee70c0a4a 100644
--- a/pkg/wallet/wallet.go
+++ b/pkg/wallet/wallet.go
@@ -261,15 +261,13 @@ func CreateDataVaultKeyPairs(userID string, ctx provider, options ...UnlockOptio
}
// unlock key manager
- token, err := keyManager().createKeyManager(profile, ctx.StorageProvider(), opts)
+ kmsm, err := keyManager().createKeyManager(profile, ctx.StorageProvider(), opts)
if err != nil {
return fmt.Errorf("failed to get key manager: %w", err)
}
- defer keyManager().removeKeyManager(userID)
-
// update profile
- err = updateProfile(token, profile)
+ err = updateProfile(kmsm, profile)
if err != nil {
return fmt.Errorf("failed to create key pairs: %w", err)
}
@@ -357,13 +355,18 @@ func (c *Wallet) Open(options ...UnlockOptions) (string, error) {
}
// unlock key manager
- token, err := keyManager().createKeyManager(c.profile, c.storeProvider, opts)
+ keyManager, err := keyManager().createKeyManager(c.profile, c.storeProvider, opts)
+ if err != nil {
+ return "", err
+ }
+
+ token, err := sessionManager().createSession(c.profile.User, keyManager, opts.tokenExpiry)
if err != nil {
return "", err
}
// open content store using token
- err = c.contents.Open(token, opts)
+ err = c.contents.Open(keyManager, opts)
if err != nil {
// close wallet if it fails to open store
c.Close()
@@ -377,7 +380,7 @@ func (c *Wallet) Open(options ...UnlockOptions) (string, error) {
// Close expires token issued to this VC wallet, removes the key manager instance and closes wallet content store.
// returns false if token is not found or already expired for this wallet user.
func (c *Wallet) Close() bool {
- return keyManager().removeKeyManager(c.userID) && c.contents.Close()
+ return sessionManager().closeSession(c.userID) && c.contents.Close()
}
// Export produces a serialized exported wallet representation.
@@ -627,12 +630,12 @@ func (c *Wallet) Derive(authToken string, credential CredentialToDerive, options
// - keyType: type of the key to be created.
//
func (c *Wallet) CreateKeyPair(authToken string, keyType kms.KeyType) (*KeyPair, error) {
- kmgr, err := keyManager().getKeyManger(authToken)
+ session, err := sessionManager().getSession(authToken)
if err != nil {
- return nil, ErrInvalidAuthToken
+ return nil, err
}
- kid, pubBytes, err := kmgr.CreateAndExportPubKeyBytes(keyType)
+ kid, pubBytes, err := session.KeyManager.CreateAndExportPubKeyBytes(keyType)
if err != nil {
return nil, err
}
@@ -1455,15 +1458,9 @@ func addContext(v interface{}, ldcontext string) {
}
}
-func updateProfile(auth string, profile *profile) error {
- // get key manager
- keyManager, err := keyManager().getKeyManger(auth)
- if err != nil {
- return err
- }
-
+func updateProfile(keyManager kms.KeyManager, profile *profile) error {
// setup key pairs
- err = profile.setupEDVEncryptionKey(keyManager)
+ err := profile.setupEDVEncryptionKey(keyManager)
if err != nil {
return fmt.Errorf("failed to create EDV encryption key pair: %w", err)
}
diff --git a/pkg/wallet/wallet_test.go b/pkg/wallet/wallet_test.go
index 21763db23..ecb29a5a9 100644
--- a/pkg/wallet/wallet_test.go
+++ b/pkg/wallet/wallet_test.go
@@ -403,31 +403,25 @@ func TestCreateDataVaultKeyPairs(t *testing.T) {
})
t.Run("test update profile errors", func(t *testing.T) {
- require.Error(t, updateProfile("invalid", &profile{}))
-
- token := uuid.New().String()
-
- require.NoError(t, keyManager().saveKeyManger(uuid.New().String(), token,
- &mockkms.KeyManager{CreateKeyFn: func(kt kms.KeyType) (s string, i interface{}, e error) {
- if kt == kms.HMACSHA256Tag256Type {
- return "", nil, errors.New(sampleWalletErr)
- }
- return "", nil, nil
- }}, 1000*time.Millisecond))
+ kmgr := &mockkms.KeyManager{CreateKeyFn: func(kt kms.KeyType) (s string, i interface{}, e error) {
+ if kt == kms.HMACSHA256Tag256Type {
+ return "", nil, errors.New(sampleWalletErr)
+ }
+ return "", nil, nil
+ }}
- err := updateProfile(token, &profile{EDVConf: &edvConf{}})
+ err := updateProfile(kmgr, &profile{EDVConf: &edvConf{}})
require.Error(t, err)
require.Contains(t, err.Error(), "failed to create EDV MAC key pair")
- require.NoError(t, keyManager().saveKeyManger(uuid.New().String(), token,
- &mockkms.KeyManager{CreateKeyFn: func(kt kms.KeyType) (s string, i interface{}, e error) {
- if kt == kms.NISTP256ECDHKWType {
- return "", nil, errors.New(sampleWalletErr)
- }
- return "", nil, nil
- }}, 1000*time.Millisecond))
+ kmgr = &mockkms.KeyManager{CreateKeyFn: func(kt kms.KeyType) (s string, i interface{}, e error) {
+ if kt == kms.NISTP256ECDHKWType {
+ return "", nil, errors.New(sampleWalletErr)
+ }
+ return "", nil, nil
+ }}
- err = updateProfile(token, &profile{EDVConf: &edvConf{}})
+ err = updateProfile(kmgr, &profile{EDVConf: &edvConf{}})
require.Error(t, err)
require.Contains(t, err.Error(), "failed to create EDV encryption key pair")
})
@@ -1182,8 +1176,13 @@ func TestWallet_Issue(t *testing.T) {
defer walletInstance.Close()
// import keys manually
- kmgr, err := keyManager().getKeyManger(authToken)
+ session, err := sessionManager().getSession(authToken)
+ require.NotEmpty(t, session)
require.NoError(t, err)
+
+ kmgr := session.KeyManager
+ require.NotEmpty(t, kmgr)
+
edPriv := ed25519.PrivateKey(base58.Decode(pkBase58))
// nolint: errcheck, gosec
kmgr.ImportPrivateKey(edPriv, kms.ED25519, kms.WithKeyID(kid))
@@ -1210,11 +1209,12 @@ func TestWallet_Issue(t *testing.T) {
defer walletInstance.Close()
// import keys manually
- kmgr, err := keyManager().getKeyManger(authToken)
+ session, err := sessionManager().getSession(authToken)
+ require.NotEmpty(t, session)
require.NoError(t, err)
edPriv := ed25519.PrivateKey(base58.Decode(pkBase58))
// nolint: errcheck, gosec
- kmgr.ImportPrivateKey(edPriv, kms.ED25519, kms.WithKeyID(kid))
+ session.KeyManager.ImportPrivateKey(edPriv, kms.ED25519, kms.WithKeyID(kid))
// sign with just controller
result, err := walletInstance.Issue(authToken, testdata.SampleUDCVC, &ProofOptions{
@@ -1239,11 +1239,13 @@ func TestWallet_Issue(t *testing.T) {
defer walletInstance.Close()
// import keys manually
- kmgr, err := keyManager().getKeyManger(authToken)
+ session, err := sessionManager().getSession(authToken)
+ require.NotEmpty(t, session)
require.NoError(t, err)
+
edPriv := ed25519.PrivateKey(base58.Decode(pkBase58))
// nolint: errcheck, gosec
- kmgr.ImportPrivateKey(edPriv, kms.ED25519, kms.WithKeyID(kid))
+ session.KeyManager.ImportPrivateKey(edPriv, kms.ED25519, kms.WithKeyID(kid))
// issue
result, err := walletInstance.Issue(authToken, testdata.SampleUDCVC, &ProofOptions{
@@ -1268,8 +1270,13 @@ func TestWallet_Issue(t *testing.T) {
defer walletInstance.Close()
// import keys manually
- kmgr, err := keyManager().getKeyManger(authToken)
+ session, err := sessionManager().getSession(authToken)
+ require.NotEmpty(t, session)
require.NoError(t, err)
+
+ kmgr := session.KeyManager
+ require.NotEmpty(t, kmgr)
+
edPriv := ed25519.PrivateKey(base58.Decode(pkBase58))
// nolint: errcheck, gosec
kmgr.ImportPrivateKey(edPriv, kms.ED25519, kms.WithKeyID(kid))
@@ -1315,8 +1322,13 @@ func TestWallet_Issue(t *testing.T) {
defer walletInstance.Close()
// import keys manually
- kmgr, err := keyManager().getKeyManger(authToken)
+ session, err := sessionManager().getSession(authToken)
+ require.NotEmpty(t, session)
require.NoError(t, err)
+
+ kmgr := session.KeyManager
+ require.NotEmpty(t, kmgr)
+
privKeyBBS, err := bbs12381g2pub.UnmarshalPrivateKey(base58.Decode(pkBBSBase58))
require.NoError(t, err)
// nolint: errcheck, gosec
@@ -1354,8 +1366,13 @@ func TestWallet_Issue(t *testing.T) {
defer walletInstance.Close()
// import keys manually
- kmgr, err := keyManager().getKeyManger(authToken)
+ session, err := sessionManager().getSession(authToken)
+ require.NotEmpty(t, session)
require.NoError(t, err)
+
+ kmgr := session.KeyManager
+ require.NotEmpty(t, kmgr)
+
edPriv := ed25519.PrivateKey(base58.Decode(pkBase58))
// nolint: errcheck, gosec
kmgr.ImportPrivateKey(edPriv, kms.ED25519, kms.WithKeyID(kid))
@@ -1447,8 +1464,13 @@ func TestWallet_Issue(t *testing.T) {
require.Contains(t, err.Error(), "cannot read data for keysetID")
// import keys manually
- kmgr, err := keyManager().getKeyManger(authToken)
+ session, err := sessionManager().getSession(authToken)
+ require.NotEmpty(t, session)
require.NoError(t, err)
+
+ kmgr := session.KeyManager
+ require.NotEmpty(t, kmgr)
+
edPriv := ed25519.PrivateKey(base58.Decode(pkBase58))
// nolint: errcheck, gosec
kmgr.ImportPrivateKey(edPriv, kms.ED25519, kms.WithKeyID(kid))
@@ -1514,9 +1536,13 @@ func TestWallet_Prove(t *testing.T) {
require.NotEmpty(t, authToken)
// import ED25519 & BLS12381G2Type keys manually
- kmgr, err := keyManager().getKeyManger(authToken)
+ session, err := sessionManager().getSession(authToken)
+ require.NotEmpty(t, session)
require.NoError(t, err)
+ kmgr := session.KeyManager
+ require.NotEmpty(t, kmgr)
+
edPriv := ed25519.PrivateKey(base58.Decode(pkBase58))
// nolint: errcheck, gosec
kmgr.ImportPrivateKey(edPriv, kms.ED25519, kms.WithKeyID(kid))
@@ -1566,8 +1592,13 @@ func TestWallet_Prove(t *testing.T) {
defer cleanup()
// import keys manually for signing presentation
- kmgr, err := keyManager().getKeyManger(authToken)
+ session, err := sessionManager().getSession(authToken)
+ require.NotEmpty(t, session)
require.NoError(t, err)
+
+ kmgr := session.KeyManager
+ require.NotEmpty(t, kmgr)
+
edPriv := ed25519.PrivateKey(base58.Decode(pkBase58))
// nolint: errcheck, gosec
kmgr.ImportPrivateKey(edPriv, kms.ED25519, kms.WithKeyID(kid))
@@ -1619,8 +1650,13 @@ func TestWallet_Prove(t *testing.T) {
defer cleanup()
// import keys manually for signing presentation
- kmgr, err := keyManager().getKeyManger(authToken)
+ session, err := sessionManager().getSession(authToken)
+ require.NotEmpty(t, session)
require.NoError(t, err)
+
+ kmgr := session.KeyManager
+ require.NotEmpty(t, kmgr)
+
edPriv := ed25519.PrivateKey(base58.Decode(pkBase58))
// nolint: errcheck, gosec
kmgr.ImportPrivateKey(edPriv, kms.ED25519, kms.WithKeyID(kid))
@@ -1679,8 +1715,13 @@ func TestWallet_Prove(t *testing.T) {
defer cleanup()
// import keys manually for signing presentation
- kmgr, err := keyManager().getKeyManger(authToken)
+ session, err := sessionManager().getSession(authToken)
+ require.NotEmpty(t, session)
require.NoError(t, err)
+
+ kmgr := session.KeyManager
+ require.NotEmpty(t, kmgr)
+
edPriv := ed25519.PrivateKey(base58.Decode(pkBase58))
// nolint: errcheck, gosec
kmgr.ImportPrivateKey(edPriv, kms.ED25519, kms.WithKeyID(kid))
@@ -1742,8 +1783,13 @@ func TestWallet_Prove(t *testing.T) {
defer cleanup()
// import keys manually for signing presentation
- kmgr, err := keyManager().getKeyManger(authToken)
+ session, err := sessionManager().getSession(authToken)
+ require.NotEmpty(t, session)
require.NoError(t, err)
+
+ kmgr := session.KeyManager
+ require.NotEmpty(t, kmgr)
+
edPriv := ed25519.PrivateKey(base58.Decode(pkBase58))
// nolint: errcheck, gosec
kmgr.ImportPrivateKey(edPriv, kms.ED25519, kms.WithKeyID(kid))
@@ -1790,8 +1836,13 @@ func TestWallet_Prove(t *testing.T) {
defer walletInstance.Close()
// import keys manually for signing presentation
- kmgr, err := keyManager().getKeyManger(authToken)
+ session, err := sessionManager().getSession(authToken)
+ require.NotEmpty(t, session)
require.NoError(t, err)
+
+ kmgr := session.KeyManager
+ require.NotEmpty(t, kmgr)
+
edPriv := ed25519.PrivateKey(base58.Decode(pkBase58))
// nolint: errcheck, gosec
kmgr.ImportPrivateKey(edPriv, kms.ED25519, kms.WithKeyID(kid))
@@ -1932,8 +1983,13 @@ func TestWallet_Prove(t *testing.T) {
require.Contains(t, err.Error(), "cannot read data for keysetID")
// import keys manually
- kmgr, err := keyManager().getKeyManger(authToken)
+ session, err := sessionManager().getSession(authToken)
+ require.NotEmpty(t, session)
require.NoError(t, err)
+
+ kmgr := session.KeyManager
+ require.NotEmpty(t, kmgr)
+
edPriv := ed25519.PrivateKey(base58.Decode(pkBase58))
// nolint: errcheck, gosec
kmgr.ImportPrivateKey(edPriv, kms.ED25519, kms.WithKeyID(kid))
@@ -2013,9 +2069,13 @@ func TestWallet_Verify(t *testing.T) {
require.NotEmpty(t, tkn)
// import keys manually
- kmgr, err := keyManager().getKeyManger(tkn)
+ session, err := sessionManager().getSession(tkn)
+ require.NotEmpty(t, session)
require.NoError(t, err)
+ kmgr := session.KeyManager
+ require.NotEmpty(t, kmgr)
+
edPriv := ed25519.PrivateKey(base58.Decode(pkBase58))
// nolint: errcheck, gosec
kmgr.ImportPrivateKey(edPriv, kms.ED25519, kms.WithKeyID(kid))
@@ -2253,9 +2313,13 @@ func TestWallet_Derive(t *testing.T) {
require.NotEmpty(t, authToken)
// import ED25519 & BLS12381G2Type keys manually
- kmgr, err := keyManager().getKeyManger(authToken)
+ session, err := sessionManager().getSession(authToken)
+ require.NotEmpty(t, session)
require.NoError(t, err)
+ kmgr := session.KeyManager
+ require.NotEmpty(t, kmgr)
+
edPriv := ed25519.PrivateKey(base58.Decode(pkBase58))
// nolint: errcheck, gosec
kmgr.ImportPrivateKey(edPriv, kms.ED25519, kms.WithKeyID(kid))
From 748fd2b202e8c120ffb6625e2a9256f4f6005d8d Mon Sep 17 00:00:00 2001
From: Filip Burlacu
Date: Tue, 7 Jun 2022 17:06:48 -0400
Subject: [PATCH 45/54] feat: interop support for did service refactor (#3257)
Signed-off-by: Filip Burlacu
---
pkg/didcomm/common/service/destination_interop.go | 11 ++++++-----
pkg/didcomm/protocol/didexchange/states.go | 13 ++++++++-----
pkg/doc/did/serialize_interop.go | 4 +++-
pkg/vdr/peer/creator.go | 10 ++--------
4 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/pkg/didcomm/common/service/destination_interop.go b/pkg/didcomm/common/service/destination_interop.go
index 0039ce3ab..6de1643b1 100644
--- a/pkg/didcomm/common/service/destination_interop.go
+++ b/pkg/didcomm/common/service/destination_interop.go
@@ -15,6 +15,7 @@ import (
"github.com/btcsuite/btcutil/base58"
+ "github.com/hyperledger/aries-framework-go/pkg/common/model"
diddoc "github.com/hyperledger/aries-framework-go/pkg/doc/did"
"github.com/hyperledger/aries-framework-go/pkg/vdr/fingerprint"
)
@@ -35,19 +36,19 @@ func CreateDestination(didDoc *diddoc.Doc) (*Destination, error) {
return nil, fmt.Errorf("create destination: missing DID doc service")
}
}
-
- if uri, err := didCommService.ServiceEndpoint.URI(); uri == "" || err != nil {
- return nil, fmt.Errorf("create destination: no service endpoint on didcomm service block in diddoc: %+v", didDoc)
+ uri, err := didCommService.ServiceEndpoint.URI()
+ if uri == "" || err != nil {
+ return nil, fmt.Errorf("create destination: no service endpoint on didcomm service block in diddoc: %#v", didDoc)
}
if len(didCommService.RecipientKeys) == 0 {
- return nil, fmt.Errorf("create destination: no recipient keys on didcomm service block in diddoc: %+v", didDoc)
+ return nil, fmt.Errorf("create destination: no recipient keys on didcomm service block in diddoc: %#v", didDoc)
}
// Interop: service keys that are raw base58 public keys should be converted to did:key format
return &Destination{
RecipientKeys: convertAnyB58Keys(didCommService.RecipientKeys),
- ServiceEndpoint: didCommService.ServiceEndpoint,
+ ServiceEndpoint: model.NewDIDCommV1Endpoint(uri),
RoutingKeys: convertAnyB58Keys(didCommService.RoutingKeys),
MediaTypeProfiles: didCommService.Accept,
}, nil
diff --git a/pkg/didcomm/protocol/didexchange/states.go b/pkg/didcomm/protocol/didexchange/states.go
index 059f297f3..a7101e4e8 100644
--- a/pkg/didcomm/protocol/didexchange/states.go
+++ b/pkg/didcomm/protocol/didexchange/states.go
@@ -46,6 +46,8 @@ const (
StateIDAbandoned = "abandoned"
ackStatusOK = "ok"
didCommServiceType = "did-communication"
+ // legacyDIDCommServiceType for aca-py interop.
+ legacyDIDCommServiceType = "IndyAgent"
// DIDComm V2 service type ref: https://identity.foundation/didcomm-messaging/spec/#did-document-service-endpoint
didCommV2ServiceType = "DIDCommMessaging"
ed25519VerificationKey2018 = "Ed25519VerificationKey2018"
@@ -430,7 +432,7 @@ func serviceTypeByMediaProfile(mediaTypeProfiles []string) string {
// nolint:gocyclo,funlen
func (ctx *context) handleInboundRequest(request *Request, options *options,
connRec *connectionstore.Record) (stateAction, *connectionstore.Record, error) {
- logger.Debugf("handling request: %+v", request)
+ logger.Debugf("handling request: %#v", request)
// Interop: aca-py issue https://github.com/hyperledger/aries-cloudagent-python/issues/1048
if ctx.doACAPyInterop && !strings.HasPrefix(request.DID, "did") {
@@ -473,12 +475,12 @@ func (ctx *context) handleInboundRequest(request *Request, options *options,
if myDID != "" { // empty myDID means a new DID was just created and not exchanged yet, use did:key instead
senderVerKey, err = recipientKey(responseDidDoc)
if err != nil {
- return nil, nil, fmt.Errorf("handle inbound request: %w", err)
+ return nil, nil, fmt.Errorf("get recipient key: %w", err)
}
} else {
senderVerKey, err = recipientKeyAsDIDKey(responseDidDoc)
if err != nil {
- return nil, nil, fmt.Errorf("handle inbound request: %w", err)
+ return nil, nil, fmt.Errorf("get recipient key as did:key: %w", err)
}
}
@@ -702,13 +704,14 @@ func (ctx *context) getMyDIDDoc(pubDID string, routerConnections []string, servi
var svc did.Service
- if serviceType == didCommServiceType {
+ switch serviceType {
+ case didCommServiceType, legacyDIDCommServiceType:
svc = did.Service{
Type: didCommServiceType,
ServiceEndpoint: model.NewDIDCommV1Endpoint(serviceEndpoint),
RoutingKeys: routingKeys,
}
- } else if serviceType == didCommV2ServiceType {
+ case didCommV2ServiceType:
svc = did.Service{
ServiceEndpoint: model.NewDIDCommV2Endpoint([]model.DIDCommV2Endpoint{
{URI: serviceEndpoint, RoutingKeys: routingKeys},
diff --git a/pkg/doc/did/serialize_interop.go b/pkg/doc/did/serialize_interop.go
index 7679b2c12..33f7f0a3b 100644
--- a/pkg/doc/did/serialize_interop.go
+++ b/pkg/doc/did/serialize_interop.go
@@ -113,8 +113,10 @@ func populateRawServicesInterop(services []Service, didID, baseURI string) []map
rawService[jsonldID] = makeRelativeDIDURL(services[i].ID, baseURI, didID)
}
+ uri, _ := services[i].ServiceEndpoint.URI()
+
rawService[jsonldType] = services[i].Type
- rawService[jsonldServicePoint] = services[i].ServiceEndpoint
+ rawService[jsonldServicePoint] = uri
rawService[jsonldRecipientKeys] = recipientKeys
rawService[jsonldRoutingKeys] = routingKeys
rawService[jsonldPriority] = services[i].Priority
diff --git a/pkg/vdr/peer/creator.go b/pkg/vdr/peer/creator.go
index 09c3d5307..73be4fb00 100644
--- a/pkg/vdr/peer/creator.go
+++ b/pkg/vdr/peer/creator.go
@@ -13,7 +13,6 @@ import (
"github.com/google/uuid"
- "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/didcomm/transport"
"github.com/hyperledger/aries-framework-go/pkg/doc/did"
@@ -28,8 +27,6 @@ const (
x25519KeyAgreementKey2019 = "X25519KeyAgreementKey2019"
)
-var logger = log.New("aries-framework/pkg/vdr/peer")
-
// Create create new DID Document.
// TODO https://github.com/hyperledger/aries-framework-go/issues/2466
func (v *VDR) Create(didDoc *did.Doc, opts ...vdrapi.DIDMethodOption) (*did.DocResolution, error) {
@@ -95,15 +92,12 @@ func build(didDoc *did.Doc, docOpts *vdrapi.DIDMethodOpts) (*did.DocResolution,
didDoc.Service[i].Type = v
}
- uri, e := didDoc.Service[i].ServiceEndpoint.URI()
- if e != nil {
- logger.Debugf("service endpoint URI returned error %w, ignoring..", e)
- }
+ uri, _ := didDoc.Service[i].ServiceEndpoint.URI() // nolint:errcheck
// nolint:nestif
if uri == "" && docOpts.Values[DefaultServiceEndpoint] != nil {
switch didDoc.Service[i].Type {
- case vdrapi.DIDCommServiceType:
+ case vdrapi.DIDCommServiceType, "IndyAgent":
v, ok := docOpts.Values[DefaultServiceEndpoint].(string)
if !ok {
return nil, fmt.Errorf("defaultServiceEndpoint not string")
From 119077b0ec85f8b11bfaad58a89854c38a2615f4 Mon Sep 17 00:00:00 2001
From: Baha <29608896+Baha-sk@users.noreply.github.com>
Date: Fri, 10 Jun 2022 09:38:18 -0400
Subject: [PATCH 46/54] refactor: remote cryptobox URLs renamed to /wrap and
/unwrap (#3259)
this change updates the remote CryptoBox api URIs to point to remote KMS's key /wrap and /unwrap to match ECDH-ES and ECDH-1PU key wrapping.
This change requires the KMS server to udpate /easy to /wrap, /easyOpen and /sealOpen to /unwrap
Signed-off-by: Baha Shaaban
---
pkg/kms/webkms/crypto_box.go | 11 ++--
pkg/kms/webkms/crypto_box_test.go | 6 +--
test/bdd/features/didexchange_e2e_sdk.feature | 39 +++++++-------
test/bdd/features/webkms.feature | 51 ++++++++++---------
4 files changed, 54 insertions(+), 53 deletions(-)
diff --git a/pkg/kms/webkms/crypto_box.go b/pkg/kms/webkms/crypto_box.go
index 9d70324a2..fb3f7ed4e 100644
--- a/pkg/kms/webkms/crypto_box.go
+++ b/pkg/kms/webkms/crypto_box.go
@@ -53,9 +53,8 @@ type sealOpenResp struct {
}
const (
- easyURL = "/easy"
- easyOpenURL = "/easyopen"
- sealOpenURL = "/sealopen"
+ wrapURL = "/wrap"
+ unwrapURL = "/unwrap"
)
// CryptoBox provides an elliptic-curve-based authenticated encryption scheme executed on a remote key server
@@ -87,7 +86,7 @@ func (b *CryptoBox) Easy(payload, nonce, theirPub []byte, myKID string) ([]byte,
easyStart := time.Now()
keyURL := b.km.buildKIDURL(myKID)
- destination := keyURL + easyURL
+ destination := keyURL + wrapURL
httpReqJSON := &easyReq{
Payload: payload,
@@ -134,7 +133,7 @@ func (b *CryptoBox) Easy(payload, nonce, theirPub []byte, myKID string) ([]byte,
// theirPub is the public key used to decrypt directly, while myPub is used to identify the private key to be used.
func (b *CryptoBox) EasyOpen(cipherText, nonce, theirPub, myPub []byte) ([]byte, error) {
easyOpenStart := time.Now()
- destination := b.km.keystoreURL + easyOpenURL
+ destination := b.km.keystoreURL + unwrapURL
httpReqJSON := &easyOpenReq{
Ciphertext: cipherText,
@@ -214,7 +213,7 @@ func (b *CryptoBox) Seal(payload, theirEncPub []byte, randSource io.Reader) ([]b
// and uses that along with the recipient private key corresponding to myPub to decrypt the message.
func (b *CryptoBox) SealOpen(cipherText, myPub []byte) ([]byte, error) {
sealOpenStart := time.Now()
- destination := b.km.keystoreURL + sealOpenURL
+ destination := b.km.keystoreURL + unwrapURL
httpReqJSON := &sealOpenReq{
Ciphertext: cipherText,
diff --git a/pkg/kms/webkms/crypto_box_test.go b/pkg/kms/webkms/crypto_box_test.go
index d759d2f4f..3fa719965 100644
--- a/pkg/kms/webkms/crypto_box_test.go
+++ b/pkg/kms/webkms/crypto_box_test.go
@@ -141,7 +141,7 @@ func processPOSTSealOpenRequest(w http.ResponseWriter, r *http.Request, recipien
destination := "https://" + r.Host + r.URL.Path
// nolint:nestif // test code
- if strings.LastIndex(r.URL.Path, sealOpenURL) == len(r.URL.Path)-len(sealOpenURL) {
+ if strings.LastIndex(r.URL.Path, unwrapURL) == len(r.URL.Path)-len(unwrapURL) {
reqBody, err := ioutil.ReadAll(r.Body)
if err != nil {
return fmt.Errorf("read ciphertext request for SealOpen failed [%s, %w]", destination, err)
@@ -323,7 +323,7 @@ func processPOSTEasyOpenRequest(w http.ResponseWriter, r *http.Request, recPrivK
destination := "https://" + r.Host + r.URL.Path
// nolint:nestif // test code
- if strings.LastIndex(r.URL.Path, easyURL) == len(r.URL.Path)-len(easyURL) {
+ if strings.LastIndex(r.URL.Path, wrapURL) == len(r.URL.Path)-len(wrapURL) {
reqBody, err := ioutil.ReadAll(r.Body)
if err != nil {
return fmt.Errorf("read ciphertext request for EasyOpen failed [%s, %w]", destination, err)
@@ -376,7 +376,7 @@ func processPOSTEasyOpenRequest(w http.ResponseWriter, r *http.Request, recPrivK
}
// nolint:nestif // test code
- if strings.LastIndex(r.URL.Path, easyOpenURL) == len(r.URL.Path)-len(easyOpenURL) {
+ if strings.LastIndex(r.URL.Path, unwrapURL) == len(r.URL.Path)-len(unwrapURL) {
reqBody, err := ioutil.ReadAll(r.Body)
if err != nil {
return fmt.Errorf("read ciphertext request for EasyOpen failed [%s, %w]", destination, err)
diff --git a/test/bdd/features/didexchange_e2e_sdk.feature b/test/bdd/features/didexchange_e2e_sdk.feature
index ad033b30a..5fc8a411e 100644
--- a/test/bdd/features/didexchange_e2e_sdk.feature
+++ b/test/bdd/features/didexchange_e2e_sdk.feature
@@ -46,22 +46,23 @@ Feature: Decentralized Identifier(DID) exchange between the agents using SDK
Then "Alice" retrieves connection record and validates that connection state is "completed"
And "Bob" retrieves connection record and validates that connection state is "completed"
- @webkms_didexchange_e2e_sdk
- Scenario: did exchange e2e flow with agents using webkms
- Given "Sudesh" agent is running on "localhost" port "random" with "http" as the transport provider using webkms with key server at "https://localhost:8076" URL, using "did:key:dummy-sample:sudesh" controller
- And "Sudesh" creates did exchange client
- And "Sudesh" registers to receive notification for post state event "completed"
-
- Given "Firas" agent is running on "localhost" port "random" with "http" as the transport provider using webkms with key server at "https://localhost:8076" URL, using "did:key:dummy-sample:firas" controller
- And "Firas" creates did exchange client
-
- When "Firas" registers to receive notification for post state event "completed"
- And "Sudesh" creates invitation
- And "Firas" receives invitation from "Sudesh"
- And "Firas" approves invitation request
- And "Sudesh" approves did exchange request
- And "Sudesh" waits for post state event "completed"
- And "Firas" waits for post state event "completed"
-
- Then "Sudesh" retrieves connection record and validates that connection state is "completed"
- And "Firas" retrieves connection record and validates that connection state is "completed"
+ #TODO uncomment below test once KMS server refactors /easy to /wrap URL
+# @webkms_didexchange_e2e_sdk
+# Scenario: did exchange e2e flow with agents using webkms
+# Given "Sudesh" agent is running on "localhost" port "random" with "http" as the transport provider using webkms with key server at "https://localhost:8076" URL, using "did:key:dummy-sample:sudesh" controller
+# And "Sudesh" creates did exchange client
+# And "Sudesh" registers to receive notification for post state event "completed"
+#
+# Given "Firas" agent is running on "localhost" port "random" with "http" as the transport provider using webkms with key server at "https://localhost:8076" URL, using "did:key:dummy-sample:firas" controller
+# And "Firas" creates did exchange client
+#
+# When "Firas" registers to receive notification for post state event "completed"
+# And "Sudesh" creates invitation
+# And "Firas" receives invitation from "Sudesh"
+# And "Firas" approves invitation request
+# And "Sudesh" approves did exchange request
+# And "Sudesh" waits for post state event "completed"
+# And "Firas" waits for post state event "completed"
+#
+# Then "Sudesh" retrieves connection record and validates that connection state is "completed"
+# And "Firas" retrieves connection record and validates that connection state is "completed"
diff --git a/test/bdd/features/webkms.feature b/test/bdd/features/webkms.feature
index ab57778f8..f5bcf7a72 100644
--- a/test/bdd/features/webkms.feature
+++ b/test/bdd/features/webkms.feature
@@ -89,31 +89,32 @@ Feature: Decentralized Identifier(DID) exchange between the agents using SDK
When "Baha" unwrap wrapped key from "Andrii" with sender key
Then "Baha" gets the same CEK as "Andrii"
- Scenario: User A anonymously encrypts ("easy") a payload for User B, User B decrypts ("easy open") it
- Given "Andrii" agent is running on "localhost" port "random" with "http" as the transport provider using webkms with key server at "https://localhost:8076" URL, using "did:key:dummy-sample:sudesh" controller
- And "Andrii" create and export "ED25519" key
-
- Given "Baha" agent is running on "localhost" port "random" with "http" as the transport provider using webkms with key server at "https://localhost:8076" URL, using "did:key:dummy-sample:sudesh" controller
- And "Baha" create and export "ED25519" key
-
- When "Andrii" easy "test payload" for "Baha"
- Then "Andrii" gets non-empty ciphertext
-
- When "Baha" easyOpen ciphertext from "Andrii"
- Then "Baha" gets plaintext with value "test payload"
-
- Scenario: User B decrypts ("seal open") a payload that was encrypted ("seal") by User A
- Given "Andrii" agent is running on "localhost" port "random" with "http" as the transport provider using webkms with key server at "https://localhost:8076" URL, using "did:key:dummy-sample:sudesh" controller
- And "Andrii" create and export "ED25519" key
-
- Given "Baha" agent is running on "localhost" port "random" with "http" as the transport provider using webkms with key server at "https://localhost:8076" URL, using "did:key:dummy-sample:sudesh" controller
- And "Baha" create "ED25519" key
-
- When "Baha" has sealed "test payload 2" for "Andrii"
- Then "Baha" gets non-empty ciphertext
-
- When "Andrii" sealOpen ciphertext from "Baha"
- Then "Andrii" gets plaintext with value "test payload 2"
+ #TODO uncomment and rename easy with wrap and easyOpen with unwrap when kms server switches easy to wrap and easyOpen to unwrap.
+# Scenario: User A anonymously encrypts ("easy") a payload for User B, User B decrypts ("easy open") it
+# Given "Andrii" agent is running on "localhost" port "random" with "http" as the transport provider using webkms with key server at "https://localhost:8076" URL, using "did:key:dummy-sample:sudesh" controller
+# And "Andrii" create and export "ED25519" key
+#
+# Given "Baha" agent is running on "localhost" port "random" with "http" as the transport provider using webkms with key server at "https://localhost:8076" URL, using "did:key:dummy-sample:sudesh" controller
+# And "Baha" create and export "ED25519" key
+#
+# When "Andrii" easy "test payload" for "Baha"
+# Then "Andrii" gets non-empty ciphertext
+#
+# When "Baha" easyOpen ciphertext from "Andrii"
+# Then "Baha" gets plaintext with value "test payload"
+ # TODO uncomment test and rename sealOpen with unwrap when kms server switches sealOpen with unwrap.
+# Scenario: User B decrypts ("seal open") a payload that was encrypted ("seal") by User A
+# Given "Andrii" agent is running on "localhost" port "random" with "http" as the transport provider using webkms with key server at "https://localhost:8076" URL, using "did:key:dummy-sample:sudesh" controller
+# And "Andrii" create and export "ED25519" key
+#
+# Given "Baha" agent is running on "localhost" port "random" with "http" as the transport provider using webkms with key server at "https://localhost:8076" URL, using "did:key:dummy-sample:sudesh" controller
+# And "Baha" create "ED25519" key
+#
+# When "Baha" has sealed "test payload 2" for "Andrii"
+# Then "Baha" gets non-empty ciphertext
+#
+# When "Andrii" sealOpen ciphertext from "Baha"
+# Then "Andrii" gets plaintext with value "test payload 2"
@webkms_interop_localkms
Scenario: User A with webkms wraps A256GCM key for User B with localkms, User B successfully unwraps it
From 3d817acfa48bd9c3906bbf1b60d1551349337483 Mon Sep 17 00:00:00 2001
From: Baha <29608896+Baha-sk@users.noreply.github.com>
Date: Tue, 14 Jun 2022 11:27:30 -0400
Subject: [PATCH 47/54] refactor: re enable remote kms bdd-tests with unwrapKey
(#3263)
This change updates the webkms server in bdd tests and re enables commented out webkms tests requiring cryptobox's /wrap and /unwrap operations.
closes #3262
Signed-off-by: Baha Shaaban
---
pkg/kms/webkms/crypto_box.go | 25 ++++++++-
test/bdd/features/didexchange_e2e_sdk.feature | 39 +++++++-------
test/bdd/features/webkms.feature | 51 +++++++++----------
test/bdd/fixtures/agent-rest/.env | 2 +-
.../fixtures/agent-rest/docker-compose.yml | 2 +-
5 files changed, 69 insertions(+), 50 deletions(-)
diff --git a/pkg/kms/webkms/crypto_box.go b/pkg/kms/webkms/crypto_box.go
index fb3f7ed4e..1d7e6ef96 100644
--- a/pkg/kms/webkms/crypto_box.go
+++ b/pkg/kms/webkms/crypto_box.go
@@ -14,6 +14,7 @@ import (
"golang.org/x/crypto/nacl/box"
+ "github.com/hyperledger/aries-framework-go/pkg/doc/util/jwkkid"
"github.com/hyperledger/aries-framework-go/pkg/internal/cryptoutil"
"github.com/hyperledger/aries-framework-go/pkg/kms"
)
@@ -133,7 +134,11 @@ func (b *CryptoBox) Easy(payload, nonce, theirPub []byte, myKID string) ([]byte,
// theirPub is the public key used to decrypt directly, while myPub is used to identify the private key to be used.
func (b *CryptoBox) EasyOpen(cipherText, nonce, theirPub, myPub []byte) ([]byte, error) {
easyOpenStart := time.Now()
- destination := b.km.keystoreURL + unwrapURL
+
+ destination, err := b.buildUnwrapURL(myPub)
+ if err != nil {
+ return nil, err
+ }
httpReqJSON := &easyOpenReq{
Ciphertext: cipherText,
@@ -213,7 +218,11 @@ func (b *CryptoBox) Seal(payload, theirEncPub []byte, randSource io.Reader) ([]b
// and uses that along with the recipient private key corresponding to myPub to decrypt the message.
func (b *CryptoBox) SealOpen(cipherText, myPub []byte) ([]byte, error) {
sealOpenStart := time.Now()
- destination := b.km.keystoreURL + unwrapURL
+
+ destination, err := b.buildUnwrapURL(myPub)
+ if err != nil {
+ return nil, err
+ }
httpReqJSON := &sealOpenReq{
Ciphertext: cipherText,
@@ -254,3 +263,15 @@ func (b *CryptoBox) SealOpen(cipherText, myPub []byte) ([]byte, error) {
return httpResp.Plaintext, nil
}
+
+func (b *CryptoBox) buildUnwrapURL(myPub []byte) (string, error) {
+ // remote kms requires keyID in the keyURL for unwrapURL.
+ kid, err := jwkkid.CreateKID(myPub, kms.ED25519Type)
+ if err != nil {
+ return "", err
+ }
+
+ keyURL := b.km.buildKIDURL(kid)
+
+ return keyURL + unwrapURL, nil
+}
diff --git a/test/bdd/features/didexchange_e2e_sdk.feature b/test/bdd/features/didexchange_e2e_sdk.feature
index 5fc8a411e..ad033b30a 100644
--- a/test/bdd/features/didexchange_e2e_sdk.feature
+++ b/test/bdd/features/didexchange_e2e_sdk.feature
@@ -46,23 +46,22 @@ Feature: Decentralized Identifier(DID) exchange between the agents using SDK
Then "Alice" retrieves connection record and validates that connection state is "completed"
And "Bob" retrieves connection record and validates that connection state is "completed"
- #TODO uncomment below test once KMS server refactors /easy to /wrap URL
-# @webkms_didexchange_e2e_sdk
-# Scenario: did exchange e2e flow with agents using webkms
-# Given "Sudesh" agent is running on "localhost" port "random" with "http" as the transport provider using webkms with key server at "https://localhost:8076" URL, using "did:key:dummy-sample:sudesh" controller
-# And "Sudesh" creates did exchange client
-# And "Sudesh" registers to receive notification for post state event "completed"
-#
-# Given "Firas" agent is running on "localhost" port "random" with "http" as the transport provider using webkms with key server at "https://localhost:8076" URL, using "did:key:dummy-sample:firas" controller
-# And "Firas" creates did exchange client
-#
-# When "Firas" registers to receive notification for post state event "completed"
-# And "Sudesh" creates invitation
-# And "Firas" receives invitation from "Sudesh"
-# And "Firas" approves invitation request
-# And "Sudesh" approves did exchange request
-# And "Sudesh" waits for post state event "completed"
-# And "Firas" waits for post state event "completed"
-#
-# Then "Sudesh" retrieves connection record and validates that connection state is "completed"
-# And "Firas" retrieves connection record and validates that connection state is "completed"
+ @webkms_didexchange_e2e_sdk
+ Scenario: did exchange e2e flow with agents using webkms
+ Given "Sudesh" agent is running on "localhost" port "random" with "http" as the transport provider using webkms with key server at "https://localhost:8076" URL, using "did:key:dummy-sample:sudesh" controller
+ And "Sudesh" creates did exchange client
+ And "Sudesh" registers to receive notification for post state event "completed"
+
+ Given "Firas" agent is running on "localhost" port "random" with "http" as the transport provider using webkms with key server at "https://localhost:8076" URL, using "did:key:dummy-sample:firas" controller
+ And "Firas" creates did exchange client
+
+ When "Firas" registers to receive notification for post state event "completed"
+ And "Sudesh" creates invitation
+ And "Firas" receives invitation from "Sudesh"
+ And "Firas" approves invitation request
+ And "Sudesh" approves did exchange request
+ And "Sudesh" waits for post state event "completed"
+ And "Firas" waits for post state event "completed"
+
+ Then "Sudesh" retrieves connection record and validates that connection state is "completed"
+ And "Firas" retrieves connection record and validates that connection state is "completed"
diff --git a/test/bdd/features/webkms.feature b/test/bdd/features/webkms.feature
index f5bcf7a72..ab57778f8 100644
--- a/test/bdd/features/webkms.feature
+++ b/test/bdd/features/webkms.feature
@@ -89,32 +89,31 @@ Feature: Decentralized Identifier(DID) exchange between the agents using SDK
When "Baha" unwrap wrapped key from "Andrii" with sender key
Then "Baha" gets the same CEK as "Andrii"
- #TODO uncomment and rename easy with wrap and easyOpen with unwrap when kms server switches easy to wrap and easyOpen to unwrap.
-# Scenario: User A anonymously encrypts ("easy") a payload for User B, User B decrypts ("easy open") it
-# Given "Andrii" agent is running on "localhost" port "random" with "http" as the transport provider using webkms with key server at "https://localhost:8076" URL, using "did:key:dummy-sample:sudesh" controller
-# And "Andrii" create and export "ED25519" key
-#
-# Given "Baha" agent is running on "localhost" port "random" with "http" as the transport provider using webkms with key server at "https://localhost:8076" URL, using "did:key:dummy-sample:sudesh" controller
-# And "Baha" create and export "ED25519" key
-#
-# When "Andrii" easy "test payload" for "Baha"
-# Then "Andrii" gets non-empty ciphertext
-#
-# When "Baha" easyOpen ciphertext from "Andrii"
-# Then "Baha" gets plaintext with value "test payload"
- # TODO uncomment test and rename sealOpen with unwrap when kms server switches sealOpen with unwrap.
-# Scenario: User B decrypts ("seal open") a payload that was encrypted ("seal") by User A
-# Given "Andrii" agent is running on "localhost" port "random" with "http" as the transport provider using webkms with key server at "https://localhost:8076" URL, using "did:key:dummy-sample:sudesh" controller
-# And "Andrii" create and export "ED25519" key
-#
-# Given "Baha" agent is running on "localhost" port "random" with "http" as the transport provider using webkms with key server at "https://localhost:8076" URL, using "did:key:dummy-sample:sudesh" controller
-# And "Baha" create "ED25519" key
-#
-# When "Baha" has sealed "test payload 2" for "Andrii"
-# Then "Baha" gets non-empty ciphertext
-#
-# When "Andrii" sealOpen ciphertext from "Baha"
-# Then "Andrii" gets plaintext with value "test payload 2"
+ Scenario: User A anonymously encrypts ("easy") a payload for User B, User B decrypts ("easy open") it
+ Given "Andrii" agent is running on "localhost" port "random" with "http" as the transport provider using webkms with key server at "https://localhost:8076" URL, using "did:key:dummy-sample:sudesh" controller
+ And "Andrii" create and export "ED25519" key
+
+ Given "Baha" agent is running on "localhost" port "random" with "http" as the transport provider using webkms with key server at "https://localhost:8076" URL, using "did:key:dummy-sample:sudesh" controller
+ And "Baha" create and export "ED25519" key
+
+ When "Andrii" easy "test payload" for "Baha"
+ Then "Andrii" gets non-empty ciphertext
+
+ When "Baha" easyOpen ciphertext from "Andrii"
+ Then "Baha" gets plaintext with value "test payload"
+
+ Scenario: User B decrypts ("seal open") a payload that was encrypted ("seal") by User A
+ Given "Andrii" agent is running on "localhost" port "random" with "http" as the transport provider using webkms with key server at "https://localhost:8076" URL, using "did:key:dummy-sample:sudesh" controller
+ And "Andrii" create and export "ED25519" key
+
+ Given "Baha" agent is running on "localhost" port "random" with "http" as the transport provider using webkms with key server at "https://localhost:8076" URL, using "did:key:dummy-sample:sudesh" controller
+ And "Baha" create "ED25519" key
+
+ When "Baha" has sealed "test payload 2" for "Andrii"
+ Then "Baha" gets non-empty ciphertext
+
+ When "Andrii" sealOpen ciphertext from "Baha"
+ Then "Andrii" gets plaintext with value "test payload 2"
@webkms_interop_localkms
Scenario: User A with webkms wraps A256GCM key for User B with localkms, User B successfully unwraps it
diff --git a/test/bdd/fixtures/agent-rest/.env b/test/bdd/fixtures/agent-rest/.env
index 0f5e46400..77176566b 100644
--- a/test/bdd/fixtures/agent-rest/.env
+++ b/test/bdd/fixtures/agent-rest/.env
@@ -115,7 +115,7 @@ COUCHDB_PORT=5984
# KMS
KMS_REST_IMAGE=ghcr.io/trustbloc-cicd/kms
-KMS_REST_TAG=v0.1.8-snapshot-3f3ef05
+KMS_REST_TAG=v0.1.9-snapshot-9389ad5
# Remote JSON-LD context provider configuration
CONTEXT_PROVIDER_URL=https://file-server.example.com:9099/agent-startup-contexts.json
diff --git a/test/bdd/fixtures/agent-rest/docker-compose.yml b/test/bdd/fixtures/agent-rest/docker-compose.yml
index d4c1d1ff7..58881f9ac 100644
--- a/test/bdd/fixtures/agent-rest/docker-compose.yml
+++ b/test/bdd/fixtures/agent-rest/docker-compose.yml
@@ -313,7 +313,7 @@ services:
- KMS_CACHE_EXPIRATION=10m
- KMS_SECRET_LOCK_TYPE=local
- KMS_SECRET_LOCK_KEY_PATH=/etc/tls/secret-lock.key
- - KMS_ZCAP_ENABLE=false
+ - KMS_AUTH_DISABLE=true
- KMS_LOG_LEVEL=debug
ports:
- 8076:8076
From 82112d172a78a5385b229bacce86008f91eefbe2 Mon Sep 17 00:00:00 2001
From: Volodymyr Kubiv <62515092+vkubiv@users.noreply.github.com>
Date: Fri, 17 Jun 2022 17:19:11 +0300
Subject: [PATCH 48/54] feat: validate data model of objects saved in a wallet.
(#3261)
Signed-off-by: Volodymyr Kubiv
---
pkg/controller/command/vcwallet/command.go | 12 +-
.../command/vcwallet/command_test.go | 29 ++-
.../testdata/context/context3.jsonld | 0
.../testdata/context/context4.jsonld | 0
.../testdata/context/context5.jsonld | 0
.../testdata/context/context6.jsonld | 0
.../jsonld/testdata/context/wallet_v1.jsonld | 58 ++++++
pkg/doc/jsonld/validate.go | 189 ++++++++++++++++++
.../validate_test.go} | 101 ++++++----
pkg/doc/ldcontext/embed/embed_contexts.go | 7 +
.../w3c-ccg.github.io/wallet-v1.jsonld | 58 ++++++
pkg/doc/{verifiable => util/json}/json.go | 26 +--
.../{verifiable => util/json}/json_test.go | 18 +-
pkg/doc/verifiable/common.go | 5 +-
pkg/doc/verifiable/credential.go | 26 ++-
pkg/doc/verifiable/credential_bbs.go | 3 +-
pkg/doc/verifiable/credential_bbs_test.go | 5 +-
pkg/doc/verifiable/credential_jwt.go | 3 +-
pkg/doc/verifiable/credential_ldp_test.go | 7 +-
pkg/doc/verifiable/credential_test.go | 9 +-
pkg/doc/verifiable/jsonld.go | 135 -------------
pkg/doc/verifiable/presentation.go | 12 +-
pkg/doc/verifiable/presentation_ldp_test.go | 3 +-
pkg/wallet/contents.go | 44 +++-
pkg/wallet/contents_test.go | 125 ++++++++----
pkg/wallet/options.go | 10 +
pkg/wallet/wallet.go | 2 +-
pkg/wallet/wallet_test.go | 2 +-
28 files changed, 617 insertions(+), 272 deletions(-)
rename pkg/doc/{verifiable => jsonld}/testdata/context/context3.jsonld (100%)
rename pkg/doc/{verifiable => jsonld}/testdata/context/context4.jsonld (100%)
rename pkg/doc/{verifiable => jsonld}/testdata/context/context5.jsonld (100%)
rename pkg/doc/{verifiable => jsonld}/testdata/context/context6.jsonld (100%)
create mode 100644 pkg/doc/jsonld/testdata/context/wallet_v1.jsonld
create mode 100644 pkg/doc/jsonld/validate.go
rename pkg/doc/{verifiable/jsonld_test.go => jsonld/validate_test.go} (83%)
create mode 100644 pkg/doc/ldcontext/embed/third_party/w3c-ccg.github.io/wallet-v1.jsonld
rename pkg/doc/{verifiable => util/json}/json.go (70%)
rename pkg/doc/{verifiable => util/json}/json_test.go (83%)
diff --git a/pkg/controller/command/vcwallet/command.go b/pkg/controller/command/vcwallet/command.go
index b3002b2d7..619e1a9ca 100644
--- a/pkg/controller/command/vcwallet/command.go
+++ b/pkg/controller/command/vcwallet/command.go
@@ -172,6 +172,8 @@ type Config struct {
// Default token expiry for all wallet profiles created.
// Will be used only if wallet unlock request doesn't supply default timeout value.
DefaultTokenExpiry time.Duration
+ // Indicate if a data model of json-ld content stored in the wallet should be validated.
+ ValidateDataModel bool
}
// provider contains dependencies for the verifiable credential wallet command controller
@@ -415,7 +417,15 @@ func (o *Command) Add(rw io.Writer, req io.Reader) command.Error {
return command.NewExecuteError(AddToWalletErrorCode, err)
}
- err = vcWallet.Add(request.Auth, request.ContentType, request.Content, wallet.AddByCollection(request.CollectionID))
+ addOpts := []wallet.AddContentOptions{
+ wallet.AddByCollection(request.CollectionID),
+ }
+
+ if o.config.ValidateDataModel {
+ addOpts = append(addOpts, wallet.ValidateContent())
+ }
+
+ err = vcWallet.Add(request.Auth, request.ContentType, request.Content, addOpts...)
if err != nil {
logutil.LogInfo(logger, CommandName, AddMethod, err.Error())
diff --git a/pkg/controller/command/vcwallet/command_test.go b/pkg/controller/command/vcwallet/command_test.go
index 773e7b150..f9a54f525 100644
--- a/pkg/controller/command/vcwallet/command_test.go
+++ b/pkg/controller/command/vcwallet/command_test.go
@@ -716,8 +716,8 @@ func TestCommand_AddRemoveGetGetAll(t *testing.T) {
require.NoError(t, cmdErr)
})
- t.Run("add a metadata to wallet", func(t *testing.T) {
- cmd := New(mockctx, &Config{})
+ t.Run("add a metadata to wallet with validation", func(t *testing.T) {
+ cmd := New(mockctx, &Config{ValidateDataModel: true})
var b bytes.Buffer
@@ -779,6 +779,31 @@ func TestCommand_AddRemoveGetGetAll(t *testing.T) {
require.Len(t, response.Contents, count)
})
+ t.Run("add a collection to wallet with validation failed", func(t *testing.T) {
+ const orgCollectionWithInvalidStructure = `{
+ "@context": ["https://w3id.org/wallet/v1"],
+ "id": "did:example:acme123456789abcdefghi",
+ "type": "Organization",
+ "name": "Acme Corp.",
+ "image": "https://via.placeholder.com/150",
+ "description" : "A software company.",
+ "tags": ["professional", "organization"],
+ "incorrectProp": "incorrectProp",
+ "correlation": ["4058a72a-9523-11ea-bb37-0242ac130002"]
+ }`
+
+ cmd := New(mockctx, &Config{ValidateDataModel: true})
+
+ var b bytes.Buffer
+
+ cmdErr := cmd.Add(&b, getReader(t, &AddContentRequest{
+ Content: []byte(orgCollectionWithInvalidStructure),
+ ContentType: wallet.Collection,
+ WalletAuth: WalletAuth{UserID: sampleUser1, Auth: token1},
+ }))
+ require.Contains(t, cmdErr.Error(), "JSON-LD doc has different structure after compaction")
+ })
+
t.Run("get all credentials from wallet by collection ID", func(t *testing.T) {
const orgCollection = `{
"@context": ["https://w3id.org/wallet/v1"],
diff --git a/pkg/doc/verifiable/testdata/context/context3.jsonld b/pkg/doc/jsonld/testdata/context/context3.jsonld
similarity index 100%
rename from pkg/doc/verifiable/testdata/context/context3.jsonld
rename to pkg/doc/jsonld/testdata/context/context3.jsonld
diff --git a/pkg/doc/verifiable/testdata/context/context4.jsonld b/pkg/doc/jsonld/testdata/context/context4.jsonld
similarity index 100%
rename from pkg/doc/verifiable/testdata/context/context4.jsonld
rename to pkg/doc/jsonld/testdata/context/context4.jsonld
diff --git a/pkg/doc/verifiable/testdata/context/context5.jsonld b/pkg/doc/jsonld/testdata/context/context5.jsonld
similarity index 100%
rename from pkg/doc/verifiable/testdata/context/context5.jsonld
rename to pkg/doc/jsonld/testdata/context/context5.jsonld
diff --git a/pkg/doc/verifiable/testdata/context/context6.jsonld b/pkg/doc/jsonld/testdata/context/context6.jsonld
similarity index 100%
rename from pkg/doc/verifiable/testdata/context/context6.jsonld
rename to pkg/doc/jsonld/testdata/context/context6.jsonld
diff --git a/pkg/doc/jsonld/testdata/context/wallet_v1.jsonld b/pkg/doc/jsonld/testdata/context/wallet_v1.jsonld
new file mode 100644
index 000000000..51efb0dc4
--- /dev/null
+++ b/pkg/doc/jsonld/testdata/context/wallet_v1.jsonld
@@ -0,0 +1,58 @@
+{
+ "@context": [
+ {
+ "@version": 1.1
+ },
+ {
+ "id": "@id",
+ "type": "@type",
+
+ "UniversalWallet2020": "https://w3id.org/wallet#UniversalWallet2020",
+ "encryptedWalletContents": {
+ "@id": "https://w3id.org/wallet#encryptedWalletContents",
+ "@type": "@json"
+ },
+
+ "Key": "https://w3id.org/wallet#Key",
+ "Secret": "https://w3id.org/wallet#Secret",
+ "Entropy": "https://w3id.org/wallet#Entropy",
+ "Profile": "https://w3id.org/wallet#Profile",
+ "Mnemonic": "https://w3id.org/wallet#Mnemonic",
+ "MetaData": "https://w3id.org/wallet#MetaData",
+
+ "correlation": "https://w3id.org/wallet#correlation",
+ "tags": "https://w3id.org/wallet#tags",
+ "note": "https://w3id.org/wallet#note",
+ "target": "https://w3id.org/wallet#target",
+ "quorum": "https://w3id.org/wallet#quorum",
+ "multibase": "https://w3id.org/wallet#multibase",
+ "hdPath": "https://w3id.org/wallet#hdPath",
+
+ "amount": "https://schema.org/amount",
+ "currency": "https://schema.org/currency",
+ "value": "https://schema.org/value",
+
+ "publicKeyJwk": {
+ "@id": "https://w3id.org/security#publicKeyJwk",
+ "@type": "@json"
+ },
+ "privateKeyJwk": {
+ "@id": "https://w3id.org/security#privateKeyJwk",
+ "@type": "@json"
+ },
+ "privateKeyBase58": "https://w3id.org/security#privateKeyBase58",
+ "privateKeyWebKms": "https://w3id.org/security#privateKeyWebKms",
+ "privateKeySecureEnclave": "https://w3id.org/security#privateKeySecureEnclave",
+
+ "Organization": "http://schema.org/Organization",
+ "Person": "http://schema.org/Person",
+ "name": "http://schema.org/name",
+ "description": "http://schema.org/description",
+ "identifier": "http://schema.org/identifier",
+ "image": {
+ "@id": "http://schema.org/image",
+ "@type": "@id"
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/pkg/doc/jsonld/validate.go b/pkg/doc/jsonld/validate.go
new file mode 100644
index 000000000..36a315e7b
--- /dev/null
+++ b/pkg/doc/jsonld/validate.go
@@ -0,0 +1,189 @@
+/*
+Copyright SecureKey Technologies Inc. All Rights Reserved.
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package jsonld
+
+import (
+ "errors"
+ "fmt"
+ "reflect"
+
+ "github.com/piprate/json-gold/ld"
+
+ "github.com/hyperledger/aries-framework-go/pkg/doc/signature/jsonld"
+ "github.com/hyperledger/aries-framework-go/pkg/doc/util/json"
+)
+
+type validateOpts struct {
+ strict bool
+ jsonldDocumentLoader ld.DocumentLoader
+ externalContext []string
+}
+
+// ValidateOpts sets jsonld validation options.
+type ValidateOpts func(opts *validateOpts)
+
+// WithDocumentLoader option is for passing custom JSON-LD document loader.
+func WithDocumentLoader(jsonldDocumentLoader ld.DocumentLoader) ValidateOpts {
+ return func(opts *validateOpts) {
+ opts.jsonldDocumentLoader = jsonldDocumentLoader
+ }
+}
+
+// WithExternalContext option is for definition of external context when doing JSON-LD operations.
+func WithExternalContext(externalContext []string) ValidateOpts {
+ return func(opts *validateOpts) {
+ opts.externalContext = externalContext
+ }
+}
+
+// WithStrictValidation sets if strict validation should be used.
+func WithStrictValidation(checkStructure bool) ValidateOpts {
+ return func(opts *validateOpts) {
+ opts.strict = checkStructure
+ }
+}
+
+func getValidateOpts(options []ValidateOpts) *validateOpts {
+ result := &validateOpts{
+ strict: true,
+ }
+
+ for _, opt := range options {
+ opt(result)
+ }
+
+ return result
+}
+
+// ValidateJSONLD validates jsonld structure.
+func ValidateJSONLD(doc string, options ...ValidateOpts) error {
+ opts := getValidateOpts(options)
+
+ docMap, err := json.ToMap(doc)
+ if err != nil {
+ return fmt.Errorf("convert JSON-LD doc to map: %w", err)
+ }
+
+ jsonldProc := jsonld.Default()
+
+ docCompactedMap, err := jsonldProc.Compact(docMap,
+ nil, jsonld.WithDocumentLoader(opts.jsonldDocumentLoader),
+ jsonld.WithExternalContext(opts.externalContext...))
+ if err != nil {
+ return fmt.Errorf("compact JSON-LD document: %w", err)
+ }
+
+ if opts.strict && !mapsHaveSameStructure(docMap, docCompactedMap) {
+ return errors.New("JSON-LD doc has different structure after compaction")
+ }
+
+ return nil
+}
+
+func mapsHaveSameStructure(originalMap, compactedMap map[string]interface{}) bool {
+ original := compactMap(originalMap)
+ compacted := compactMap(compactedMap)
+
+ if reflect.DeepEqual(original, compacted) {
+ return true
+ }
+
+ if len(original) != len(compacted) {
+ return false
+ }
+
+ for k, v1 := range original {
+ v1Map, isMap := v1.(map[string]interface{})
+ if !isMap {
+ continue
+ }
+
+ v2, present := compacted[k]
+ if !present { // special case - the name of the map was mapped, cannot guess what's a new name
+ continue
+ }
+
+ v2Map, isMap := v2.(map[string]interface{})
+ if !isMap {
+ return false
+ }
+
+ if !mapsHaveSameStructure(v1Map, v2Map) {
+ return false
+ }
+ }
+
+ return true
+}
+
+func compactMap(m map[string]interface{}) map[string]interface{} {
+ mCopy := make(map[string]interface{})
+
+ for k, v := range m {
+ // ignore context
+ if k == "@context" {
+ continue
+ }
+
+ vNorm := compactValue(v)
+
+ switch kv := vNorm.(type) {
+ case []interface{}:
+ mCopy[k] = compactSlice(kv)
+
+ case map[string]interface{}:
+ mCopy[k] = compactMap(kv)
+
+ default:
+ mCopy[k] = vNorm
+ }
+ }
+
+ return mCopy
+}
+
+func compactSlice(s []interface{}) []interface{} {
+ sCopy := make([]interface{}, len(s))
+
+ for i := range s {
+ sItem := compactValue(s[i])
+
+ switch sItem := sItem.(type) {
+ case map[string]interface{}:
+ sCopy[i] = compactMap(sItem)
+
+ default:
+ sCopy[i] = sItem
+ }
+ }
+
+ return sCopy
+}
+
+func compactValue(v interface{}) interface{} {
+ switch cv := v.(type) {
+ case []interface{}:
+ // consists of only one element
+ if len(cv) == 1 {
+ return compactValue(cv[0])
+ }
+
+ return cv
+
+ case map[string]interface{}:
+ // contains "id" element only
+ if len(cv) == 1 {
+ if _, ok := cv["id"]; ok {
+ return cv["id"]
+ }
+ }
+
+ return cv
+
+ default:
+ return cv
+ }
+}
diff --git a/pkg/doc/verifiable/jsonld_test.go b/pkg/doc/jsonld/validate_test.go
similarity index 83%
rename from pkg/doc/verifiable/jsonld_test.go
rename to pkg/doc/jsonld/validate_test.go
index 6dd54d369..606aa77c4 100644
--- a/pkg/doc/verifiable/jsonld_test.go
+++ b/pkg/doc/jsonld/validate_test.go
@@ -3,7 +3,7 @@ Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
-package verifiable
+package jsonld
import (
_ "embed"
@@ -12,6 +12,7 @@ import (
"github.com/stretchr/testify/require"
+ "github.com/hyperledger/aries-framework-go/pkg/doc/ld"
"github.com/hyperledger/aries-framework-go/pkg/doc/ldcontext"
"github.com/hyperledger/aries-framework-go/pkg/internal/ldtestutil"
)
@@ -26,9 +27,12 @@ var (
context5 []byte
//go:embed testdata/context/context6.jsonld
context6 []byte
+
+ //go:embed testdata/context/wallet_v1.jsonld
+ walletV1Context []byte
)
-func Test_compactJSONLD(t *testing.T) {
+func Test_ValidateJSONLD(t *testing.T) {
t.Run("Extended both basic VC and subject model", func(t *testing.T) {
contextURL := "http://127.0.0.1?context=3"
@@ -101,9 +105,7 @@ func Test_compactJSONLD(t *testing.T) {
Content: context3,
})
- opts := &jsonldCredentialOpts{jsonldDocumentLoader: loader}
-
- err := compactJSONLD(vc, opts, true)
+ err := ValidateJSONLD(vc, WithDocumentLoader(loader))
require.NoError(t, err)
})
@@ -136,14 +138,12 @@ func Test_compactJSONLD(t *testing.T) {
Content: context4,
})
- opts := &jsonldCredentialOpts{jsonldDocumentLoader: loader}
-
- err := compactJSONLD(vcJSON, opts, true)
+ err := ValidateJSONLD(vcJSON, WithDocumentLoader(loader))
require.NoError(t, err)
})
}
-func Test_compactJSONLDWithExtraUndefinedFields(t *testing.T) {
+func Test_ValidateJSONLDWithExtraUndefinedFields(t *testing.T) {
contextURL := "http://127.0.0.1?context=5"
vcJSONTemplate := `
@@ -171,14 +171,12 @@ func Test_compactJSONLDWithExtraUndefinedFields(t *testing.T) {
Content: context5,
})
- opts := &jsonldCredentialOpts{jsonldDocumentLoader: loader}
-
- err := compactJSONLD(vc, opts, true)
+ err := ValidateJSONLD(vc, WithDocumentLoader(loader))
require.Error(t, err)
require.EqualError(t, err, "JSON-LD doc has different structure after compaction")
}
-func Test_compactJSONLDWithExtraUndefinedSubjectFields(t *testing.T) {
+func Test_ValidateJSONLDWithExtraUndefinedSubjectFields(t *testing.T) {
contextURL := "http://127.0.0.1?context=6"
loader := createTestDocumentLoader(t, ldcontext.Document{
@@ -214,9 +212,8 @@ func Test_compactJSONLDWithExtraUndefinedSubjectFields(t *testing.T) {
`
vcJSON := fmt.Sprintf(vcJSONTemplate, contextURL)
- opts := &jsonldCredentialOpts{jsonldDocumentLoader: loader}
- err := compactJSONLD(vcJSON, opts, true)
+ err := ValidateJSONLD(vcJSON, WithDocumentLoader(loader))
require.Error(t, err)
require.EqualError(t, err, "JSON-LD doc has different structure after compaction")
})
@@ -248,15 +245,14 @@ func Test_compactJSONLDWithExtraUndefinedSubjectFields(t *testing.T) {
`
vcJSON := fmt.Sprintf(vcJSONTemplate, contextURL)
- opts := &jsonldCredentialOpts{jsonldDocumentLoader: loader}
- err := compactJSONLD(vcJSON, opts, true)
+ err := ValidateJSONLD(vcJSON, WithDocumentLoader(loader))
require.Error(t, err)
require.EqualError(t, err, "JSON-LD doc has different structure after compaction")
})
}
-func Test_compactJSONLD_WithExtraUndefinedFieldsInProof(t *testing.T) {
+func Test_ValidateJSONLD_WithExtraUndefinedFieldsInProof(t *testing.T) {
vcJSONWithValidProof := `
{
"@context": [
@@ -283,7 +279,7 @@ func Test_compactJSONLD_WithExtraUndefinedFieldsInProof(t *testing.T) {
}
`
- err := compactJSONLD(vcJSONWithValidProof, defaultOpts(t), true)
+ err := ValidateJSONLD(vcJSONWithValidProof, WithDocumentLoader(createTestDocumentLoader(t)))
require.NoError(t, err)
// "newProp" field is present in the proof
@@ -312,14 +308,15 @@ func Test_compactJSONLD_WithExtraUndefinedFieldsInProof(t *testing.T) {
}
}`
- err = compactJSONLD(vcJSONWithInvalidProof, defaultOpts(t), true)
+ err = ValidateJSONLD(vcJSONWithInvalidProof, WithDocumentLoader(createTestDocumentLoader(t)))
+
require.Error(t, err)
require.EqualError(t, err, "JSON-LD doc has different structure after compaction")
}
-func Test_compactJSONLD_CornerErrorCases(t *testing.T) {
+func Test_ValidateJSONLD_CornerErrorCases(t *testing.T) {
t.Run("Invalid JSON input", func(t *testing.T) {
- err := compactJSONLD("not a json", defaultOpts(t), true)
+ err := ValidateJSONLD("not a json", WithDocumentLoader(createTestDocumentLoader(t)))
require.Error(t, err)
require.Contains(t, err.Error(), "convert JSON-LD doc to map")
})
@@ -340,25 +337,16 @@ func Test_compactJSONLD_CornerErrorCases(t *testing.T) {
}
`
- err := compactJSONLD(vcJSONTemplate, defaultOpts(t), true)
+ err := ValidateJSONLD(vcJSONTemplate, WithDocumentLoader(createTestDocumentLoader(t)))
require.Error(t, err)
require.Contains(t, err.Error(), "compact JSON-LD document")
})
}
-func defaultOpts(t *testing.T) *jsonldCredentialOpts {
- t.Helper()
-
- loader, err := ldtestutil.DocumentLoader()
- require.NoError(t, err)
-
- return &jsonldCredentialOpts{jsonldDocumentLoader: loader}
-}
-
// nolint:gochecknoglobals // needed to avoid Go compiler perf optimizations for benchmarks.
var MajorSink string
-func Benchmark_compactJSONLD(b *testing.B) {
+func Benchmark_ValidateJSONLD(b *testing.B) {
var sink string
b.Run("Extended both basic VC and subject model", func(b *testing.B) {
@@ -439,9 +427,7 @@ func Benchmark_compactJSONLD(b *testing.B) {
})
require.NoError(b, err)
- opts := &jsonldCredentialOpts{jsonldDocumentLoader: loader}
-
- err = compactJSONLD(vc, opts, true)
+ err = ValidateJSONLD(vc, WithDocumentLoader(loader))
require.NoError(b, err)
sink = "basic_compact_test"
@@ -485,9 +471,7 @@ func Benchmark_compactJSONLD(b *testing.B) {
})
require.NoError(b, err)
- opts := &jsonldCredentialOpts{jsonldDocumentLoader: loader}
-
- err = compactJSONLD(vcJSON, opts, true)
+ err = ValidateJSONLD(vcJSON, WithDocumentLoader(loader))
require.NoError(b, err)
sink = "extended_compact_test"
@@ -496,4 +480,43 @@ func Benchmark_compactJSONLD(b *testing.B) {
MajorSink = sink
})
})
+
+ b.Run("Extended both basic VC and subject model", func(b *testing.B) {
+ const testMetadata = `{
+ "@context": ["https://w3id.org/wallet/v1"],
+ "id": "test-id",
+ "type": "Person",
+ "name": "John Smith",
+ "image": "https://via.placeholder.com/150",
+ "description" : "Professional software developer for Acme Corp."
+ }`
+
+ b.RunParallel(func(pb *testing.PB) {
+ b.ResetTimer()
+
+ for pb.Next() {
+ loader, err := ldtestutil.DocumentLoader(ldcontext.Document{
+ URL: "https://w3id.org/wallet/v1",
+ Content: walletV1Context,
+ })
+ require.NoError(b, err)
+
+ err = ValidateJSONLD(testMetadata, WithDocumentLoader(loader))
+ require.NoError(b, err)
+
+ sink = "basic_compact_test"
+ }
+
+ MajorSink = sink
+ })
+ })
+}
+
+func createTestDocumentLoader(t *testing.T, extraContexts ...ldcontext.Document) *ld.DocumentLoader {
+ t.Helper()
+
+ loader, err := ldtestutil.DocumentLoader(extraContexts...)
+ require.NoError(t, err)
+
+ return loader
}
diff --git a/pkg/doc/ldcontext/embed/embed_contexts.go b/pkg/doc/ldcontext/embed/embed_contexts.go
index 95dbd89de..47f67e65f 100644
--- a/pkg/doc/ldcontext/embed/embed_contexts.go
+++ b/pkg/doc/ldcontext/embed/embed_contexts.go
@@ -24,6 +24,8 @@ var (
w3idDIDv1 []byte
//go:embed third_party/w3c-ccg.github.io/did_docres_v1.jsonld
w3idDIDDocRes []byte
+ //go:embed third_party/w3c-ccg.github.io/wallet-v1.jsonld
+ w3idWalletV1 []byte
//go:embed third_party/w3c-ccg.github.io/ldp-bbs2020_v1.jsonld
ldpBBS2020 []byte
//go:embed third_party/w3c-ccg.github.io/lds-jws2020_v1.jsonld
@@ -79,6 +81,11 @@ var Contexts = []ldcontext.Document{ //nolint:gochecknoglobals
DocumentURL: "https://w3c-ccg.github.io/did-resolution/contexts/did-resolution-v1.json",
Content: w3idDIDDocRes,
},
+ {
+ URL: "https://w3id.org/wallet/v1",
+ DocumentURL: "https://w3c-ccg.github.io/universal-wallet-interop-spec/contexts/wallet-v1.json",
+ Content: w3idWalletV1,
+ },
{
URL: "https://w3id.org/security/bbs/v1",
DocumentURL: "https://w3c-ccg.github.io/ldp-bbs2020/contexts/v1/",
diff --git a/pkg/doc/ldcontext/embed/third_party/w3c-ccg.github.io/wallet-v1.jsonld b/pkg/doc/ldcontext/embed/third_party/w3c-ccg.github.io/wallet-v1.jsonld
new file mode 100644
index 000000000..51efb0dc4
--- /dev/null
+++ b/pkg/doc/ldcontext/embed/third_party/w3c-ccg.github.io/wallet-v1.jsonld
@@ -0,0 +1,58 @@
+{
+ "@context": [
+ {
+ "@version": 1.1
+ },
+ {
+ "id": "@id",
+ "type": "@type",
+
+ "UniversalWallet2020": "https://w3id.org/wallet#UniversalWallet2020",
+ "encryptedWalletContents": {
+ "@id": "https://w3id.org/wallet#encryptedWalletContents",
+ "@type": "@json"
+ },
+
+ "Key": "https://w3id.org/wallet#Key",
+ "Secret": "https://w3id.org/wallet#Secret",
+ "Entropy": "https://w3id.org/wallet#Entropy",
+ "Profile": "https://w3id.org/wallet#Profile",
+ "Mnemonic": "https://w3id.org/wallet#Mnemonic",
+ "MetaData": "https://w3id.org/wallet#MetaData",
+
+ "correlation": "https://w3id.org/wallet#correlation",
+ "tags": "https://w3id.org/wallet#tags",
+ "note": "https://w3id.org/wallet#note",
+ "target": "https://w3id.org/wallet#target",
+ "quorum": "https://w3id.org/wallet#quorum",
+ "multibase": "https://w3id.org/wallet#multibase",
+ "hdPath": "https://w3id.org/wallet#hdPath",
+
+ "amount": "https://schema.org/amount",
+ "currency": "https://schema.org/currency",
+ "value": "https://schema.org/value",
+
+ "publicKeyJwk": {
+ "@id": "https://w3id.org/security#publicKeyJwk",
+ "@type": "@json"
+ },
+ "privateKeyJwk": {
+ "@id": "https://w3id.org/security#privateKeyJwk",
+ "@type": "@json"
+ },
+ "privateKeyBase58": "https://w3id.org/security#privateKeyBase58",
+ "privateKeyWebKms": "https://w3id.org/security#privateKeyWebKms",
+ "privateKeySecureEnclave": "https://w3id.org/security#privateKeySecureEnclave",
+
+ "Organization": "http://schema.org/Organization",
+ "Person": "http://schema.org/Person",
+ "name": "http://schema.org/name",
+ "description": "http://schema.org/description",
+ "identifier": "http://schema.org/identifier",
+ "image": {
+ "@id": "http://schema.org/image",
+ "@type": "@id"
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/pkg/doc/verifiable/json.go b/pkg/doc/util/json/json.go
similarity index 70%
rename from pkg/doc/verifiable/json.go
rename to pkg/doc/util/json/json.go
index 755dd8765..f5be38ada 100644
--- a/pkg/doc/verifiable/json.go
+++ b/pkg/doc/util/json/json.go
@@ -3,16 +3,16 @@ Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
-package verifiable
+package json
import (
"encoding/json"
)
-// marshalWithCustomFields marshals value merged with custom fields defined in the map into JSON bytes.
-func marshalWithCustomFields(v interface{}, cf map[string]interface{}) ([]byte, error) {
+// MarshalWithCustomFields marshals value merged with custom fields defined in the map into JSON bytes.
+func MarshalWithCustomFields(v interface{}, cf map[string]interface{}) ([]byte, error) {
// Merge value and custom fields into the joint map.
- vm, err := mergeCustomFields(v, cf)
+ vm, err := MergeCustomFields(v, cf)
if err != nil {
return nil, err
}
@@ -21,9 +21,9 @@ func marshalWithCustomFields(v interface{}, cf map[string]interface{}) ([]byte,
return json.Marshal(vm)
}
-// unmarshalWithCustomFields unmarshals JSON into value v and puts all JSON fields which do not belong to value
+// UnmarshalWithCustomFields unmarshals JSON into value v and puts all JSON fields which do not belong to value
// into custom fields map cf.
-func unmarshalWithCustomFields(data []byte, v interface{}, cf map[string]interface{}) error {
+func UnmarshalWithCustomFields(data []byte, v interface{}, cf map[string]interface{}) error {
err := json.Unmarshal(data, v)
if err != nil {
return err
@@ -60,9 +60,9 @@ func unmarshalWithCustomFields(data []byte, v interface{}, cf map[string]interfa
return nil
}
-// mergeCustomFields converts value to the JSON-like map and merges it with custom fields map cf.
-func mergeCustomFields(v interface{}, cf map[string]interface{}) (map[string]interface{}, error) {
- kf, err := toMap(v)
+// MergeCustomFields converts value to the JSON-like map and merges it with custom fields map cf.
+func MergeCustomFields(v interface{}, cf map[string]interface{}) (map[string]interface{}, error) {
+ kf, err := ToMap(v)
if err != nil {
return nil, err
}
@@ -77,7 +77,8 @@ func mergeCustomFields(v interface{}, cf map[string]interface{}) (map[string]int
return kf, nil
}
-func toMap(v interface{}) (map[string]interface{}, error) {
+// ToMap convert object, string or bytes to json object represented by map.
+func ToMap(v interface{}) (map[string]interface{}, error) {
var (
b []byte
err error
@@ -105,11 +106,12 @@ func toMap(v interface{}) (map[string]interface{}, error) {
return m, nil
}
-func toMaps(v []interface{}) ([]map[string]interface{}, error) {
+// ToMaps convert array to array of json objects.
+func ToMaps(v []interface{}) ([]map[string]interface{}, error) {
maps := make([]map[string]interface{}, len(v))
for i := range v {
- m, err := toMap(v[i])
+ m, err := ToMap(v[i])
if err != nil {
return nil, err
}
diff --git a/pkg/doc/verifiable/json_test.go b/pkg/doc/util/json/json_test.go
similarity index 83%
rename from pkg/doc/verifiable/json_test.go
rename to pkg/doc/util/json/json_test.go
index 77ec62718..461cf1e19 100644
--- a/pkg/doc/verifiable/json_test.go
+++ b/pkg/doc/util/json/json_test.go
@@ -3,7 +3,7 @@ Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
-package verifiable
+package json
import (
"encoding/json"
@@ -33,7 +33,7 @@ func Test_marshalJSON(t *testing.T) {
"boolValue": false,
"intValue": 8,
}
- actual, err := marshalWithCustomFields(&v, cf)
+ actual, err := MarshalWithCustomFields(&v, cf)
require.NoError(t, err)
expectedMap := map[string]interface{}{
@@ -49,7 +49,7 @@ func Test_marshalJSON(t *testing.T) {
t.Run("Failed JSON marshall", func(t *testing.T) {
// artificial example - pass smth which cannot be marshalled
- jsonBytes, err := marshalWithCustomFields(make(chan int), map[string]interface{}{})
+ jsonBytes, err := MarshalWithCustomFields(make(chan int), map[string]interface{}{})
require.Error(t, err)
require.Nil(t, jsonBytes)
})
@@ -68,7 +68,7 @@ func Test_unmarshalJSON(t *testing.T) {
t.Run("Successful JSON unmarshalling", func(t *testing.T) {
v := new(testJSON)
cf := make(map[string]interface{})
- err := unmarshalWithCustomFields(data, v, cf)
+ err := UnmarshalWithCustomFields(data, v, cf)
require.NoError(t, err)
expectedV := testJSON{
@@ -86,15 +86,15 @@ func Test_unmarshalJSON(t *testing.T) {
cf := make(map[string]interface{})
// invalid JSON
- err := unmarshalWithCustomFields([]byte("not JSON"), "", cf)
+ err := UnmarshalWithCustomFields([]byte("not JSON"), "", cf)
require.Error(t, err)
// unmarshallable value
- err = unmarshalWithCustomFields(data, make(chan int), cf)
+ err = UnmarshalWithCustomFields(data, make(chan int), cf)
require.Error(t, err)
// incompatible structure of value
- err = unmarshalWithCustomFields(data, new(testJSONInvalid), cf)
+ err = UnmarshalWithCustomFields(data, new(testJSONInvalid), cf)
require.Error(t, err)
})
}
@@ -111,7 +111,7 @@ func Test_toMaps(t *testing.T) {
},
}
- maps, err := toMaps(v)
+ maps, err := ToMaps(v)
require.NoError(t, err)
require.Len(t, maps, 2)
require.Equal(t, []map[string]interface{}{
@@ -119,7 +119,7 @@ func Test_toMaps(t *testing.T) {
{"a": "b"},
}, maps)
- maps, err = toMaps([]interface{}{make(chan int)})
+ maps, err = ToMaps([]interface{}{make(chan int)})
require.Error(t, err)
require.Empty(t, maps)
}
diff --git a/pkg/doc/verifiable/common.go b/pkg/doc/verifiable/common.go
index 2bb6e85d1..66f56498c 100644
--- a/pkg/doc/verifiable/common.go
+++ b/pkg/doc/verifiable/common.go
@@ -23,6 +23,7 @@ import (
"github.com/xeipuuv/gojsonschema"
"github.com/hyperledger/aries-framework-go/pkg/doc/signature/verifier"
+ jsonutil "github.com/hyperledger/aries-framework-go/pkg/doc/util/json"
vdrapi "github.com/hyperledger/aries-framework-go/pkg/framework/aries/api/vdr"
)
@@ -133,7 +134,7 @@ func (tid TypedID) MarshalJSON() ([]byte, error) {
alias := Alias(tid)
- data, err := marshalWithCustomFields(alias, tid.CustomFields)
+ data, err := jsonutil.MarshalWithCustomFields(alias, tid.CustomFields)
if err != nil {
return nil, fmt.Errorf("marshal TypedID: %w", err)
}
@@ -150,7 +151,7 @@ func (tid *TypedID) UnmarshalJSON(data []byte) error {
tid.CustomFields = make(CustomFields)
- err := unmarshalWithCustomFields(data, alias, tid.CustomFields)
+ err := jsonutil.UnmarshalWithCustomFields(data, alias, tid.CustomFields)
if err != nil {
return fmt.Errorf("unmarshal TypedID: %w", err)
}
diff --git a/pkg/doc/verifiable/credential.go b/pkg/doc/verifiable/credential.go
index e4e35d862..f4bdd885b 100644
--- a/pkg/doc/verifiable/credential.go
+++ b/pkg/doc/verifiable/credential.go
@@ -19,9 +19,11 @@ import (
"github.com/xeipuuv/gojsonschema"
"github.com/hyperledger/aries-framework-go/pkg/common/log"
+ docjsonld "github.com/hyperledger/aries-framework-go/pkg/doc/jsonld"
"github.com/hyperledger/aries-framework-go/pkg/doc/jwt"
"github.com/hyperledger/aries-framework-go/pkg/doc/signature/verifier"
"github.com/hyperledger/aries-framework-go/pkg/doc/util"
+ jsonutil "github.com/hyperledger/aries-framework-go/pkg/doc/util/json"
)
var logger = log.New("aries-framework/doc/verifiable")
@@ -408,7 +410,7 @@ func (i *Issuer) MarshalJSON() ([]byte, error) {
alias := Alias(*i)
- data, err := marshalWithCustomFields(alias, i.CustomFields)
+ data, err := jsonutil.MarshalWithCustomFields(alias, i.CustomFields)
if err != nil {
return nil, fmt.Errorf("marshal Issuer: %w", err)
}
@@ -433,7 +435,7 @@ func (i *Issuer) UnmarshalJSON(bytes []byte) error {
i.CustomFields = make(CustomFields)
- err := unmarshalWithCustomFields(bytes, alias, i.CustomFields)
+ err := jsonutil.UnmarshalWithCustomFields(bytes, alias, i.CustomFields)
if err != nil {
return fmt.Errorf("unmarshal Issuer: %w", err)
}
@@ -463,7 +465,7 @@ func (s *Subject) MarshalJSON() ([]byte, error) {
alias := Alias(*s)
- data, err := marshalWithCustomFields(alias, s.CustomFields)
+ data, err := jsonutil.MarshalWithCustomFields(alias, s.CustomFields)
if err != nil {
return nil, fmt.Errorf("marshal Subject: %w", err)
}
@@ -487,7 +489,7 @@ func (s *Subject) UnmarshalJSON(bytes []byte) error {
s.CustomFields = make(CustomFields)
- err := unmarshalWithCustomFields(bytes, alias, s.CustomFields)
+ err := jsonutil.UnmarshalWithCustomFields(bytes, alias, s.CustomFields)
if err != nil {
return fmt.Errorf("unmarshal Subject: %w", err)
}
@@ -542,7 +544,7 @@ func (rc *rawCredential) MarshalJSON() ([]byte, error) {
alias := (*Alias)(rc)
- return marshalWithCustomFields(alias, rc.CustomFields)
+ return jsonutil.MarshalWithCustomFields(alias, rc.CustomFields)
}
// UnmarshalJSON defines custom unmarshalling of rawCredential from JSON.
@@ -552,7 +554,7 @@ func (rc *rawCredential) UnmarshalJSON(data []byte) error {
alias := (*Alias)(rc)
rc.CustomFields = make(CustomFields)
- err := unmarshalWithCustomFields(data, alias, rc.CustomFields)
+ err := jsonutil.UnmarshalWithCustomFields(data, alias, rc.CustomFields)
if err != nil {
return err
}
@@ -885,7 +887,11 @@ func (vc *Credential) validateBaseContextWithExtendedValidation(vcOpts *credenti
}
func (vc *Credential) validateJSONLD(vcBytes []byte, vcOpts *credentialOpts) error {
- return compactJSONLD(string(vcBytes), &vcOpts.jsonldCredentialOpts, vcOpts.strictValidation)
+ return docjsonld.ValidateJSONLD(string(vcBytes),
+ docjsonld.WithDocumentLoader(vcOpts.jsonldCredentialOpts.jsonldDocumentLoader),
+ docjsonld.WithExternalContext(vcOpts.jsonldCredentialOpts.externalContext),
+ docjsonld.WithStrictValidation(vcOpts.strictValidation),
+ )
}
// CustomCredentialProducer is a factory for Credentials with extended data model.
@@ -1135,7 +1141,7 @@ func subjectStructToRaw(subject interface{}) (json.RawMessage, error) {
subjects[i] = sValue.Index(i).Interface()
}
- sMaps, err := toMaps(subjects)
+ sMaps, err := jsonutil.ToMaps(subjects)
if err != nil {
return nil, errors.New("subject of unknown structure")
}
@@ -1144,7 +1150,7 @@ func subjectStructToRaw(subject interface{}) (json.RawMessage, error) {
}
// convert to map and try once again
- sMap, err := toMap(subject)
+ sMap, err := jsonutil.ToMap(subject)
if err != nil {
return nil, errors.New("subject of unknown structure")
}
@@ -1367,7 +1373,7 @@ func SubjectID(subject interface{}) (string, error) { // nolint:gocyclo
default:
// convert to map and try once again
- sMap, err := toMap(subject)
+ sMap, err := jsonutil.ToMap(subject)
if err != nil {
return "", errors.New("subject of unknown structure")
}
diff --git a/pkg/doc/verifiable/credential_bbs.go b/pkg/doc/verifiable/credential_bbs.go
index 20e27365f..be2201f8f 100644
--- a/pkg/doc/verifiable/credential_bbs.go
+++ b/pkg/doc/verifiable/credential_bbs.go
@@ -11,6 +11,7 @@ import (
"fmt"
"github.com/hyperledger/aries-framework-go/pkg/doc/signature/suite/bbsblssignatureproof2020"
+ jsonutil "github.com/hyperledger/aries-framework-go/pkg/doc/util/json"
)
// GenerateBBSSelectiveDisclosure generate BBS+ selective disclosure from one BBS+ signature.
@@ -29,7 +30,7 @@ func (vc *Credential) GenerateBBSSelectiveDisclosure(revealDoc map[string]interf
suite := bbsblssignatureproof2020.New()
- vcDoc, err := toMap(vc)
+ vcDoc, err := jsonutil.ToMap(vc)
if err != nil {
return nil, err
}
diff --git a/pkg/doc/verifiable/credential_bbs_test.go b/pkg/doc/verifiable/credential_bbs_test.go
index ff4956bfa..f3d43cf11 100644
--- a/pkg/doc/verifiable/credential_bbs_test.go
+++ b/pkg/doc/verifiable/credential_bbs_test.go
@@ -19,6 +19,7 @@ import (
"github.com/hyperledger/aries-framework-go/pkg/doc/signature/suite/bbsblssignature2020"
"github.com/hyperledger/aries-framework-go/pkg/doc/signature/suite/bbsblssignatureproof2020"
"github.com/hyperledger/aries-framework-go/pkg/doc/signature/suite/ed25519signature2018"
+ jsonutil "github.com/hyperledger/aries-framework-go/pkg/doc/util/json"
"github.com/hyperledger/aries-framework-go/pkg/kms"
)
@@ -101,7 +102,7 @@ func TestCredential_GenerateBBSSelectiveDisclosure(t *testing.T) {
}
`
- revealDoc, err := toMap(revealJSON)
+ revealDoc, err := jsonutil.ToMap(revealJSON)
require.NoError(t, err)
nonce := []byte("nonce")
@@ -178,7 +179,7 @@ func TestCredential_GenerateBBSSelectiveDisclosure(t *testing.T) {
}
`
- revealDoc, err = toMap(revealJSONWithMissingIssuer)
+ revealDoc, err = jsonutil.ToMap(revealJSONWithMissingIssuer)
require.NoError(t, err)
vcWithSelectiveDisclosure, err = vc.GenerateBBSSelectiveDisclosure(revealDoc, nonce, vcOptions...)
diff --git a/pkg/doc/verifiable/credential_jwt.go b/pkg/doc/verifiable/credential_jwt.go
index 1148dfc08..97c1e56ab 100644
--- a/pkg/doc/verifiable/credential_jwt.go
+++ b/pkg/doc/verifiable/credential_jwt.go
@@ -14,6 +14,7 @@ import (
josejwt "github.com/square/go-jose/v3/jwt"
"github.com/hyperledger/aries-framework-go/pkg/doc/jwt"
+ jsonutil "github.com/hyperledger/aries-framework-go/pkg/doc/util/json"
)
const (
@@ -69,7 +70,7 @@ func newJWTCredClaims(vc *Credential, minimizeVC bool) (*JWTCredClaims, error) {
return nil, err
}
- vcMap, err := mergeCustomFields(raw, raw.CustomFields)
+ vcMap, err := jsonutil.MergeCustomFields(raw, raw.CustomFields)
if err != nil {
return nil, err
}
diff --git a/pkg/doc/verifiable/credential_ldp_test.go b/pkg/doc/verifiable/credential_ldp_test.go
index ec47b8b56..626992836 100644
--- a/pkg/doc/verifiable/credential_ldp_test.go
+++ b/pkg/doc/verifiable/credential_ldp_test.go
@@ -33,6 +33,7 @@ import (
"github.com/hyperledger/aries-framework-go/pkg/doc/signature/suite/ed25519signature2020"
"github.com/hyperledger/aries-framework-go/pkg/doc/signature/suite/jsonwebsignature2020"
sigverifier "github.com/hyperledger/aries-framework-go/pkg/doc/signature/verifier"
+ jsonutil "github.com/hyperledger/aries-framework-go/pkg/doc/util/json"
"github.com/hyperledger/aries-framework-go/pkg/kms"
"github.com/hyperledger/aries-framework-go/pkg/kms/localkms"
)
@@ -419,7 +420,7 @@ func TestExtraContextWithLDP(t *testing.T) {
// Drop https://trustbloc.github.io/context/vc/examples-v1.jsonld context where
// SupportingActivity and CredentialStatusList2017 are defined.
- vcMap, err := toMap(vcBytes)
+ vcMap, err := jsonutil.ToMap(vcBytes)
r.NoError(err)
vcMap["@context"] = baseContext
@@ -1217,7 +1218,7 @@ func TestCredential_AddLinkedDataProof(t *testing.T) {
vc, err := parseTestCredential(t, []byte(validCredential))
r.NoError(err)
- originalVCMap, err := toMap(vc)
+ originalVCMap, err := jsonutil.ToMap(vc)
r.NoError(err)
err = vc.AddLinkedDataProof(&LinkedDataProofContext{
@@ -1231,7 +1232,7 @@ func TestCredential_AddLinkedDataProof(t *testing.T) {
}, jsonldsig.WithDocumentLoader(createTestDocumentLoader(t)))
r.NoError(err)
- vcMap, err := toMap(vc)
+ vcMap, err := jsonutil.ToMap(vc)
r.NoError(err)
r.Contains(vcMap, "proof")
diff --git a/pkg/doc/verifiable/credential_test.go b/pkg/doc/verifiable/credential_test.go
index 0642c443f..5f5042c61 100644
--- a/pkg/doc/verifiable/credential_test.go
+++ b/pkg/doc/verifiable/credential_test.go
@@ -21,6 +21,7 @@ import (
"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/verifier"
+ jsonutil "github.com/hyperledger/aries-framework-go/pkg/doc/util/json"
"github.com/hyperledger/aries-framework-go/pkg/kms"
)
@@ -1622,7 +1623,7 @@ func TestParseCredentialFromRaw(t *testing.T) {
}
func TestParseCredentialFromRaw_PreserveDates(t *testing.T) {
- vcMap, err := toMap(validCredential)
+ vcMap, err := jsonutil.ToMap(validCredential)
require.NoError(t, err)
vcMap["issuanceDate"] = "2020-01-01T00:00:00.000Z"
@@ -1639,7 +1640,7 @@ func TestParseCredentialFromRaw_PreserveDates(t *testing.T) {
require.NoError(t, err)
// Check that the dates formatting is not corrupted.
- rawMap, err := toMap(vcBytes)
+ rawMap, err := jsonutil.ToMap(vcBytes)
require.NoError(t, err)
require.Contains(t, rawMap, "issuanceDate")
@@ -1960,7 +1961,7 @@ func TestMarshalCredential(t *testing.T) {
require.NoError(t, err)
require.NotNil(t, vc)
- vcMap, err := toMap(vc)
+ vcMap, err := jsonutil.ToMap(vc)
require.NoError(t, err)
require.Empty(t, vcMap["credentialSchema"])
require.NotEmpty(t, vcMap["@context"])
@@ -1971,7 +1972,7 @@ func TestMarshalCredential(t *testing.T) {
// now set schema and try again
vc.Schemas = []TypedID{{ID: "test1"}, {ID: "test2"}}
- vcMap, err = toMap(vc)
+ vcMap, err = jsonutil.ToMap(vc)
require.NoError(t, err)
require.NotEmpty(t, vcMap["credentialSchema"])
require.NotEmpty(t, vcMap["@context"])
diff --git a/pkg/doc/verifiable/jsonld.go b/pkg/doc/verifiable/jsonld.go
index a327c6cd4..786cd2ea2 100644
--- a/pkg/doc/verifiable/jsonld.go
+++ b/pkg/doc/verifiable/jsonld.go
@@ -5,14 +5,6 @@ SPDX-License-Identifier: Apache-2.0
package verifiable
-import (
- "errors"
- "fmt"
- "reflect"
-
- "github.com/hyperledger/aries-framework-go/pkg/doc/signature/jsonld"
-)
-
const (
// ContextURI is the required JSON-LD context for VCs and VPs.
ContextURI = "https://www.w3.org/2018/credentials/v1"
@@ -23,130 +15,3 @@ const (
// VPType is the required Type for Verifiable Credentials.
VPType = "VerifiablePresentation"
)
-
-func compactJSONLD(doc string, opts *jsonldCredentialOpts, strict bool) error {
- docMap, err := toMap(doc)
- if err != nil {
- return fmt.Errorf("convert JSON-LD doc to map: %w", err)
- }
-
- jsonldProc := jsonld.Default()
-
- docCompactedMap, err := jsonldProc.Compact(docMap,
- nil, jsonld.WithDocumentLoader(opts.jsonldDocumentLoader),
- jsonld.WithExternalContext(opts.externalContext...))
- if err != nil {
- return fmt.Errorf("compact JSON-LD document: %w", err)
- }
-
- if strict && !mapsHaveSameStructure(docMap, docCompactedMap) {
- return errors.New("JSON-LD doc has different structure after compaction")
- }
-
- return nil
-}
-
-func mapsHaveSameStructure(originalMap, compactedMap map[string]interface{}) bool {
- original := compactMap(originalMap)
- compacted := compactMap(compactedMap)
-
- if reflect.DeepEqual(original, compacted) {
- return true
- }
-
- if len(original) != len(compacted) {
- return false
- }
-
- for k, v1 := range original {
- v1Map, isMap := v1.(map[string]interface{})
- if !isMap {
- continue
- }
-
- v2, present := compacted[k]
- if !present { // special case - the name of the map was mapped, cannot guess what's a new name
- continue
- }
-
- v2Map, isMap := v2.(map[string]interface{})
- if !isMap {
- return false
- }
-
- if !mapsHaveSameStructure(v1Map, v2Map) {
- return false
- }
- }
-
- return true
-}
-
-func compactMap(m map[string]interface{}) map[string]interface{} {
- mCopy := make(map[string]interface{})
-
- for k, v := range m {
- // ignore context
- if k == "@context" {
- continue
- }
-
- vNorm := compactValue(v)
-
- switch kv := vNorm.(type) {
- case []interface{}:
- mCopy[k] = compactSlice(kv)
-
- case map[string]interface{}:
- mCopy[k] = compactMap(kv)
-
- default:
- mCopy[k] = vNorm
- }
- }
-
- return mCopy
-}
-
-func compactSlice(s []interface{}) []interface{} {
- sCopy := make([]interface{}, len(s))
-
- for i := range s {
- sItem := compactValue(s[i])
-
- switch sItem := sItem.(type) {
- case map[string]interface{}:
- sCopy[i] = compactMap(sItem)
-
- default:
- sCopy[i] = sItem
- }
- }
-
- return sCopy
-}
-
-func compactValue(v interface{}) interface{} {
- switch cv := v.(type) {
- case []interface{}:
- // consists of only one element
- if len(cv) == 1 {
- return compactValue(cv[0])
- }
-
- return cv
-
- case map[string]interface{}:
- // contains "id" element only
- if len(cv) == 1 {
- if _, ok := cv["id"]; ok {
- return cv["id"]
- }
- }
-
- return cv
-
- default:
- return cv
- }
-}
diff --git a/pkg/doc/verifiable/presentation.go b/pkg/doc/verifiable/presentation.go
index c33114768..da2f2d625 100644
--- a/pkg/doc/verifiable/presentation.go
+++ b/pkg/doc/verifiable/presentation.go
@@ -14,8 +14,10 @@ import (
"github.com/xeipuuv/gojsonschema"
"github.com/hyperledger/aries-framework-go/pkg/doc/jose"
+ docjsonld "github.com/hyperledger/aries-framework-go/pkg/doc/jsonld"
"github.com/hyperledger/aries-framework-go/pkg/doc/jwt"
"github.com/hyperledger/aries-framework-go/pkg/doc/signature/verifier"
+ jsonutil "github.com/hyperledger/aries-framework-go/pkg/doc/util/json"
)
const basePresentationSchema = `
@@ -315,7 +317,7 @@ func (rp *rawPresentation) MarshalJSON() ([]byte, error) {
alias := (*Alias)(rp)
- return marshalWithCustomFields(alias, rp.CustomFields)
+ return jsonutil.MarshalWithCustomFields(alias, rp.CustomFields)
}
// UnmarshalJSON defines custom unmarshalling of rawPresentation from JSON.
@@ -325,7 +327,7 @@ func (rp *rawPresentation) UnmarshalJSON(data []byte) error {
alias := (*Alias)(rp)
rp.CustomFields = make(CustomFields)
- err := unmarshalWithCustomFields(data, alias, rp.CustomFields)
+ err := jsonutil.UnmarshalWithCustomFields(data, alias, rp.CustomFields)
if err != nil {
return err
}
@@ -536,7 +538,11 @@ func validateVP(data []byte, opts *presentationOpts) error {
}
func validateVPJSONLD(vpBytes []byte, opts *presentationOpts) error {
- return compactJSONLD(string(vpBytes), &opts.jsonldCredentialOpts, opts.strictValidation)
+ return docjsonld.ValidateJSONLD(string(vpBytes),
+ docjsonld.WithDocumentLoader(opts.jsonldCredentialOpts.jsonldDocumentLoader),
+ docjsonld.WithExternalContext(opts.jsonldCredentialOpts.externalContext),
+ docjsonld.WithStrictValidation(opts.strictValidation),
+ )
}
func validateVPJSONSchema(data []byte) error {
diff --git a/pkg/doc/verifiable/presentation_ldp_test.go b/pkg/doc/verifiable/presentation_ldp_test.go
index 97681e8fe..cb4eada2a 100644
--- a/pkg/doc/verifiable/presentation_ldp_test.go
+++ b/pkg/doc/verifiable/presentation_ldp_test.go
@@ -14,6 +14,7 @@ import (
"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/ed25519signature2018"
+ jsonutil "github.com/hyperledger/aries-framework-go/pkg/doc/util/json"
"github.com/hyperledger/aries-framework-go/pkg/kms"
)
@@ -81,7 +82,7 @@ func TestPresentation_AddLinkedDataProof(t *testing.T) {
vpJSON, err := vp.MarshalJSON()
r.NoError(err)
- vpMap, err := toMap(vpJSON)
+ vpMap, err := jsonutil.ToMap(vpJSON)
r.NoError(err)
r.Contains(vpMap, "proof")
diff --git a/pkg/wallet/contents.go b/pkg/wallet/contents.go
index 6cd6ea658..9d07ecbcf 100644
--- a/pkg/wallet/contents.go
+++ b/pkg/wallet/contents.go
@@ -18,8 +18,10 @@ import (
"time"
"github.com/bluele/gcache"
+ "github.com/piprate/json-gold/ld"
"github.com/hyperledger/aries-framework-go/pkg/doc/did"
+ "github.com/hyperledger/aries-framework-go/pkg/doc/jsonld"
"github.com/hyperledger/aries-framework-go/pkg/framework/aries/api/vdr"
"github.com/hyperledger/aries-framework-go/pkg/kms"
"github.com/hyperledger/aries-framework-go/spi/storage"
@@ -104,17 +106,24 @@ var (
// contentStore is store for wallet contents for given user profile.
type contentStore struct {
- storeID string
- provider *storageProvider
- open storeOpenHandle
- close storeCloseHandle
- lock sync.RWMutex
+ storeID string
+ provider *storageProvider
+ open storeOpenHandle
+ close storeCloseHandle
+ lock sync.RWMutex
+ jsonldDocumentLoader ld.DocumentLoader
}
// newContentStore returns new wallet content store instance.
// will use underlying storage provider as content storage if profile doesn't have edv settings.
-func newContentStore(p storage.Provider, pr *profile) *contentStore {
- contents := &contentStore{open: storeLocked, close: noOp, provider: newWalletStorageProvider(pr, p), storeID: pr.ID}
+func newContentStore(p storage.Provider, jsonldDocumentLoader ld.DocumentLoader, pr *profile) *contentStore {
+ contents := &contentStore{
+ open: storeLocked,
+ close: noOp,
+ provider: newWalletStorageProvider(pr, p),
+ storeID: pr.ID,
+ jsonldDocumentLoader: jsonldDocumentLoader,
+ }
if store, err := storeManager().get(pr.ID); err == nil {
contents.updateStoreHandles(store)
@@ -178,7 +187,7 @@ func (cs *contentStore) Close() bool {
// if content document id is missing from content, then system generated id will be used as key for storage.
// returns error if content with same ID already exists in store.
// For replacing already existing content, use 'Remove() + Add()'.
-func (cs *contentStore) Save(auth string, ct ContentType, content []byte, options ...AddContentOptions) error {
+func (cs *contentStore) Save(auth string, ct ContentType, content []byte, options ...AddContentOptions) error { //nolint:lll,gocyclo
opts := &addContentOpts{}
for _, option := range options {
@@ -187,6 +196,10 @@ func (cs *contentStore) Save(auth string, ct ContentType, content []byte, option
switch ct {
case Collection, Metadata, Connection, Credential:
+ if err := cs.checkDataModel(content, opts); err != nil {
+ return err
+ }
+
key, err := getContentID(content)
if err != nil {
return err
@@ -212,6 +225,10 @@ func (cs *contentStore) Save(auth string, ct ContentType, content []byte, option
return cs.safeSave(auth, getContentKeyPrefix(ct, docRes.DIDDocument.ID), content, storage.Tag{Name: ct.Name()})
case Key:
+ if err := cs.checkDataModel(content, opts); err != nil {
+ return err
+ }
+
// never save keys in store, just import them into kms
var key keyContent
@@ -423,6 +440,17 @@ func (cs *contentStore) GetAllByCollection(auth,
return result, nil
}
+func (cs *contentStore) checkDataModel(content []byte, opts *addContentOpts) error {
+ if opts.validateDataModel {
+ err := jsonld.ValidateJSONLD(string(content), jsonld.WithDocumentLoader(cs.jsonldDocumentLoader))
+ if err != nil {
+ return fmt.Errorf("incorrect document structure: %w", err)
+ }
+ }
+
+ return nil
+}
+
func getContentID(content []byte) (string, error) {
var cid contentID
if err := json.Unmarshal(content, &cid); err != nil {
diff --git a/pkg/wallet/contents_test.go b/pkg/wallet/contents_test.go
index 70650cff2..3f237db04 100644
--- a/pkg/wallet/contents_test.go
+++ b/pkg/wallet/contents_test.go
@@ -17,7 +17,9 @@ import (
"github.com/hyperledger/aries-framework-go/component/storage/edv"
"github.com/hyperledger/aries-framework-go/internal/testdata"
+ "github.com/hyperledger/aries-framework-go/pkg/doc/ld"
vdrapi "github.com/hyperledger/aries-framework-go/pkg/framework/aries/api/vdr"
+ "github.com/hyperledger/aries-framework-go/pkg/internal/ldtestutil"
mockkms "github.com/hyperledger/aries-framework-go/pkg/mock/kms"
mockstorage "github.com/hyperledger/aries-framework-go/pkg/mock/storage"
"github.com/hyperledger/aries-framework-go/pkg/mock/vdr"
@@ -120,16 +122,21 @@ const (
"didResolutionMetadata": {}
}`
sampleKeyContentBase58Valid = `{
+ "@context": ["https://w3id.org/wallet/v1"],
+ "id": "did:example:123456789abcdefghi#key-1",
+ "type": "Ed25519VerificationKey2018",
+ "privateKeyBase58":"zJRjGFZydU5DBdS2p5qbiUzDFAxbXTkjiDuGPksMBbY5TNyEsGfK4a4WGKjBCh1zeNryeuKtPotp8W1ESnwP71y"
+ }`
+ sampleKeyContentBase58WithInvalidField = `{
"@context": ["https://w3id.org/wallet/v1"],
"id": "did:example:123456789abcdefghi#key-1",
- "controller": "did:example:123456789abcdefghi",
+ "controller": "did:example:123456789abcdefghi",
"type": "Ed25519VerificationKey2018",
"privateKeyBase58":"zJRjGFZydU5DBdS2p5qbiUzDFAxbXTkjiDuGPksMBbY5TNyEsGfK4a4WGKjBCh1zeNryeuKtPotp8W1ESnwP71y"
}`
sampleKeyContentJwkValid = `{
"@context": ["https://w3id.org/wallet/v1"],
- "id": "did:example:123456789abcdefghi#z6MkiEh8RQL83nkPo8ehDeX7",
- "controller": "did:example:123456789abcdefghi",
+ "id": "did:example:123456789abcdefghi#z6MkiEh8RQL83nkPo8ehDeX7",
"type": "Ed25519VerificationKey2018",
"privateKeyJwk": {
"kty": "OKP",
@@ -193,7 +200,7 @@ func TestContentStores(t *testing.T) {
sp := getMockStorageProvider()
// create new store
- contentStore := newContentStore(sp, &profile{ID: uuid.New().String()})
+ contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
require.Empty(t, sp.config.TagNames)
@@ -245,7 +252,7 @@ func TestContentStores(t *testing.T) {
require.NoError(t, err)
// create new store
- contentStore := newContentStore(sp, profileInfo)
+ contentStore := newContentStore(sp, createTestDocumentLoader(t), profileInfo)
require.NotEmpty(t, contentStore)
require.Empty(t, sp.config.TagNames)
@@ -267,7 +274,7 @@ func TestContentStores(t *testing.T) {
t.Run("open store - failure", func(t *testing.T) {
sp := getMockStorageProvider()
- contentStore := newContentStore(sp, &profile{ID: uuid.New().String()})
+ contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()})
// open store error
sp.ErrOpenStoreHandle = errors.New(sampleContenttErr)
@@ -287,7 +294,7 @@ func TestContentStores(t *testing.T) {
sp.ErrOpenStoreHandle = nil
sp.failure = nil
sp.Store.ErrClose = errors.New(sampleContenttErr)
- contentStore = newContentStore(sp, &profile{ID: uuid.New().String()})
+ contentStore = newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()})
require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
require.True(t, contentStore.Close())
@@ -296,7 +303,7 @@ func TestContentStores(t *testing.T) {
t.Run("save to store - success", func(t *testing.T) {
sp := getMockStorageProvider()
- contentStore := newContentStore(sp, &profile{ID: uuid.New().String()})
+ contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
@@ -316,7 +323,7 @@ func TestContentStores(t *testing.T) {
t.Run("save content to store without ID - success", func(t *testing.T) {
sp := getMockStorageProvider()
- contentStore := newContentStore(sp, &profile{ID: uuid.New().String()})
+ contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
@@ -328,7 +335,7 @@ func TestContentStores(t *testing.T) {
t.Run("save to doc resolution to store - success", func(t *testing.T) {
sp := getMockStorageProvider()
- contentStore := newContentStore(sp, &profile{ID: uuid.New().String()})
+ contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
@@ -354,7 +361,7 @@ func TestContentStores(t *testing.T) {
sp := getMockStorageProvider()
sampleUser := uuid.New().String()
- contentStore := newContentStore(sp, &profile{ID: sampleUser})
+ contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: sampleUser})
require.NotEmpty(t, contentStore)
// wallet locked
@@ -388,11 +395,11 @@ func TestContentStores(t *testing.T) {
require.NotEmpty(t, tkn)
// import base58 private key
- err = contentStore.Save(tkn, Key, []byte(sampleKeyContentBase58Valid))
+ err = contentStore.Save(tkn, Key, []byte(sampleKeyContentBase58Valid), ValidateContent())
require.NoError(t, err)
// import jwk private key
- err = contentStore.Save(tkn, Key, []byte(sampleKeyContentJwkValid))
+ err = contentStore.Save(tkn, Key, []byte(sampleKeyContentJwkValid), ValidateContent())
require.NoError(t, err)
// import using invalid auth token
@@ -400,11 +407,46 @@ func TestContentStores(t *testing.T) {
require.True(t, errors.Is(err, ErrWalletLocked))
})
+ t.Run("save key to store - invalid jsonld", func(t *testing.T) {
+ sp := getMockStorageProvider()
+ sampleUser := uuid.New().String()
+
+ contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: sampleUser})
+ require.NotEmpty(t, contentStore)
+
+ // unlock keymanager
+ masterLock, err := getDefaultSecretLock(samplePassPhrase)
+ require.NoError(t, err)
+
+ masterLockCipherText, err := createMasterLock(masterLock)
+ require.NoError(t, err)
+ require.NotEmpty(t, masterLockCipherText)
+
+ profileInfo := &profile{
+ User: sampleUser,
+ MasterLockCipher: masterLockCipherText,
+ }
+
+ kmgr, err := keyManager().createKeyManager(profileInfo, mockstorage.NewMockStoreProvider(),
+ &unlockOpts{passphrase: samplePassPhrase})
+ require.NotEmpty(t, kmgr)
+ require.NoError(t, err)
+
+ tkn, err := sessionManager().createSession(profileInfo.User, kmgr, 500*time.Millisecond)
+
+ require.NoError(t, err)
+ require.NotEmpty(t, tkn)
+
+ // import base58 private key
+ err = contentStore.Save(tkn, Key, []byte(sampleKeyContentBase58WithInvalidField), ValidateContent())
+ require.Contains(t, err.Error(), "JSON-LD doc has different structure after compaction")
+ })
+
t.Run("save key to store - failure", func(t *testing.T) {
sp := getMockStorageProvider()
sampleUser := uuid.New().String()
- contentStore := newContentStore(sp, &profile{ID: sampleUser})
+ contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: sampleUser})
require.NotEmpty(t, contentStore)
// wallet locked
@@ -416,7 +458,7 @@ func TestContentStores(t *testing.T) {
t.Run("save to doc resolution to store - failure", func(t *testing.T) {
sp := getMockStorageProvider()
- contentStore := newContentStore(sp, &profile{ID: uuid.New().String()})
+ contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
err := contentStore.Save(token, DIDResolutionResponse, []byte(sampleContentInvalid))
@@ -427,7 +469,7 @@ func TestContentStores(t *testing.T) {
t.Run("save to store - failures", func(t *testing.T) {
sp := getMockStorageProvider()
- contentStore := newContentStore(sp, &profile{ID: uuid.New().String()})
+ contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
// invalid content type
@@ -443,7 +485,7 @@ func TestContentStores(t *testing.T) {
// store errors
sp.Store.ErrPut = errors.New(sampleContenttErr)
- contentStore = newContentStore(sp, &profile{ID: uuid.New().String()})
+ contentStore = newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
// wallet locked
@@ -465,7 +507,7 @@ func TestContentStores(t *testing.T) {
t.Run("save to invalid content type - validation", func(t *testing.T) {
sp := getMockStorageProvider()
- contentStore := newContentStore(sp, &profile{ID: uuid.New().String()})
+ contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
err := contentStore.Save(token, "Test", []byte("{}"))
@@ -476,7 +518,7 @@ func TestContentStores(t *testing.T) {
t.Run("save duplicate items - validation", func(t *testing.T) {
sp := getMockStorageProvider()
- contentStore := newContentStore(sp, &profile{ID: uuid.New().String()})
+ contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
@@ -493,7 +535,7 @@ func TestContentStores(t *testing.T) {
t.Run("get from store - success", func(t *testing.T) {
sp := getMockStorageProvider()
- contentStore := newContentStore(sp, &profile{ID: uuid.New().String()})
+ contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
@@ -512,7 +554,7 @@ func TestContentStores(t *testing.T) {
sp := getMockStorageProvider()
sp.Store.ErrGet = errors.New(sampleContenttErr)
- contentStore := newContentStore(sp, &profile{ID: uuid.New().String()})
+ contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
content, err := contentStore.Get(token, "did:example:123456789abcdefghi", Collection)
@@ -531,7 +573,7 @@ func TestContentStores(t *testing.T) {
t.Run("remove from store - success", func(t *testing.T) {
sp := getMockStorageProvider()
- contentStore := newContentStore(sp, &profile{ID: uuid.New().String()})
+ contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
@@ -560,7 +602,7 @@ func TestContentStores(t *testing.T) {
sp := getMockStorageProvider()
sp.Store.ErrDelete = errors.New(sampleContenttErr)
- contentStore := newContentStore(sp, &profile{ID: uuid.New().String()})
+ contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
@@ -620,7 +662,7 @@ func TestContentStore_GetAll(t *testing.T) {
t.Run("get all content from store for credential type - success", func(t *testing.T) {
sp := getMockStorageProvider()
- contentStore := newContentStore(sp, &profile{ID: uuid.New().String()})
+ contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
@@ -657,7 +699,7 @@ func TestContentStore_GetAll(t *testing.T) {
sp := getMockStorageProvider()
// wallet locked
- contentStore := newContentStore(sp, &profile{ID: uuid.New().String()})
+ contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()})
allVcs, err := contentStore.GetAll(token, Credential)
require.True(t, errors.Is(err, ErrWalletLocked))
@@ -676,7 +718,7 @@ func TestContentStore_GetAll(t *testing.T) {
// iterator value error
sp.MockStoreProvider.Store.ErrKey = errors.New(sampleContenttErr + uuid.New().String())
- contentStore = newContentStore(sp, &profile{ID: uuid.New().String()})
+ contentStore = newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
@@ -687,7 +729,7 @@ func TestContentStore_GetAll(t *testing.T) {
// iterator next error
sp.MockStoreProvider.Store.ErrNext = errors.New(sampleContenttErr + uuid.New().String())
- contentStore = newContentStore(sp, &profile{ID: uuid.New().String()})
+ contentStore = newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
@@ -700,7 +742,7 @@ func TestContentStore_GetAll(t *testing.T) {
// iterator next error
sp.MockStoreProvider.Store.ErrQuery = errors.New(sampleContenttErr + uuid.New().String())
- contentStore = newContentStore(sp, &profile{ID: uuid.New().String()})
+ contentStore = newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
@@ -719,7 +761,7 @@ func TestContentDIDResolver(t *testing.T) {
t.Run("create new content store - success", func(t *testing.T) {
sp := getMockStorageProvider()
- contentStore := newContentStore(sp, &profile{ID: uuid.New().String()})
+ contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
@@ -745,7 +787,7 @@ func TestContentDIDResolver(t *testing.T) {
t.Run("create new content store - errors", func(t *testing.T) {
sp := getMockStorageProvider()
- contentStore := newContentStore(sp, &profile{ID: uuid.New().String()})
+ contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
contentVDR := newContentBasedVDR(token, &vdr.MockVDRegistry{}, contentStore)
@@ -843,7 +885,7 @@ func TestContentStore_Collections(t *testing.T) {
t.Run("contents by collection - success", func(t *testing.T) {
sp := getMockStorageProvider()
- contentStore := newContentStore(sp, &profile{ID: uuid.New().String()})
+ contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
@@ -909,7 +951,7 @@ func TestContentStore_Collections(t *testing.T) {
t.Run("contents by collection - failure", func(t *testing.T) {
sp := getMockStorageProvider()
- contentStore := newContentStore(sp, &profile{ID: uuid.New().String()})
+ contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
@@ -931,7 +973,7 @@ func TestContentStore_Collections(t *testing.T) {
// get content error
sp.MockStoreProvider.Store.ErrGet = errors.New(sampleContenttErr + uuid.New().String())
- contentStore = newContentStore(sp, &profile{ID: uuid.New().String()})
+ contentStore = newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
@@ -942,7 +984,7 @@ func TestContentStore_Collections(t *testing.T) {
// iterator value error
sp.MockStoreProvider.Store.ErrValue = errors.New(sampleContenttErr + uuid.New().String())
- contentStore = newContentStore(sp, &profile{ID: uuid.New().String()})
+ contentStore = newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
@@ -953,7 +995,7 @@ func TestContentStore_Collections(t *testing.T) {
// iterator value error
sp.MockStoreProvider.Store.ErrKey = errors.New(sampleContenttErr + uuid.New().String())
- contentStore = newContentStore(sp, &profile{ID: uuid.New().String()})
+ contentStore = newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
@@ -964,7 +1006,7 @@ func TestContentStore_Collections(t *testing.T) {
// iterator next error
sp.MockStoreProvider.Store.ErrNext = errors.New(sampleContenttErr + uuid.New().String())
- contentStore = newContentStore(sp, &profile{ID: uuid.New().String()})
+ contentStore = newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
@@ -975,7 +1017,7 @@ func TestContentStore_Collections(t *testing.T) {
// iterator next error
sp.MockStoreProvider.Store.ErrQuery = errors.New(sampleContenttErr + uuid.New().String())
- contentStore = newContentStore(sp, &profile{ID: uuid.New().String()})
+ contentStore = newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()})
require.NotEmpty(t, contentStore)
require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{}))
@@ -1010,3 +1052,12 @@ func (s *mockStorageProvider) GetStoreConfig(name string) (storage.StoreConfigur
func getMockStorageProvider() *mockStorageProvider {
return &mockStorageProvider{MockStoreProvider: mockstorage.NewMockStoreProvider()}
}
+
+func createTestDocumentLoader(t *testing.T) *ld.DocumentLoader {
+ t.Helper()
+
+ loader, err := ldtestutil.DocumentLoader()
+ require.NoError(t, err)
+
+ return loader
+}
diff --git a/pkg/wallet/options.go b/pkg/wallet/options.go
index 07623eead..052ad2e85 100644
--- a/pkg/wallet/options.go
+++ b/pkg/wallet/options.go
@@ -272,6 +272,9 @@ type AddContentOptions func(opts *addContentOpts)
type addContentOpts struct {
// ID of the collection to which the content belongs.
collectionID string
+
+ // indicated if the model of data saved into the wallet should be validated.
+ validateDataModel bool
}
// AddByCollection option for grouping wallet contents by collection ID.
@@ -281,6 +284,13 @@ func AddByCollection(collectionID string) AddContentOptions {
}
}
+// ValidateContent enables data model validations of adding content.
+func ValidateContent() AddContentOptions {
+ return func(opts *addContentOpts) {
+ opts.validateDataModel = true
+ }
+}
+
// GetAllContentsOptions is option for getting all contents from wallet.
type GetAllContentsOptions func(opts *getAllContentsOpts)
diff --git a/pkg/wallet/wallet.go b/pkg/wallet/wallet.go
index ee70c0a4a..a50ec5dc4 100644
--- a/pkg/wallet/wallet.go
+++ b/pkg/wallet/wallet.go
@@ -209,7 +209,7 @@ func New(userID string, ctx provider) (*Wallet, error) {
profile: profile,
storeProvider: ctx.StorageProvider(),
walletCrypto: ctx.Crypto(),
- contents: newContentStore(ctx.StorageProvider(), profile),
+ contents: newContentStore(ctx.StorageProvider(), ctx.JSONLDDocumentLoader(), profile),
vdr: ctx.VDRegistry(),
jsonldDocumentLoader: ctx.JSONLDDocumentLoader(),
presentProofClient: presentProofClient,
diff --git a/pkg/wallet/wallet_test.go b/pkg/wallet/wallet_test.go
index ecb29a5a9..4385b3e46 100644
--- a/pkg/wallet/wallet_test.go
+++ b/pkg/wallet/wallet_test.go
@@ -721,7 +721,7 @@ func TestWallet_OpenClose(t *testing.T) {
// corrupt content store
wallet.contents = newContentStore(&mockstorage.MockStoreProvider{
ErrOpenStoreHandle: fmt.Errorf(sampleWalletErr),
- }, wallet.profile)
+ }, createTestDocumentLoader(t), wallet.profile)
// get token
token, err := wallet.Open(WithUnlockByAuthorizationToken(sampleRemoteKMSAuth))
From 566dff81e2ab98c0e33ffa4cbcee1bb926857c4f Mon Sep 17 00:00:00 2001
From: Filip Burlacu
Date: Wed, 29 Jun 2022 11:54:41 -0400
Subject: [PATCH 49/54] feat: vcwallet support for GNAP authorization (#3266)
Signed-off-by: Filip Burlacu
---
pkg/controller/command/vcwallet/command.go | 24 +++++++++++++++++-----
pkg/controller/command/vcwallet/models.go | 4 ++++
2 files changed, 23 insertions(+), 5 deletions(-)
diff --git a/pkg/controller/command/vcwallet/command.go b/pkg/controller/command/vcwallet/command.go
index 619e1a9ca..429dbf07a 100644
--- a/pkg/controller/command/vcwallet/command.go
+++ b/pkg/controller/command/vcwallet/command.go
@@ -1023,7 +1023,8 @@ func prepareUnlockOptions(rqst *UnlockWalletRequest, conf *Config) ([]wallet.Unl
if rqst.WebKMSAuth != nil {
var webKMSHeader func(*http.Request) (*http.Header, error)
- if rqst.WebKMSAuth.Capability != "" { // zcap ld signing
+ switch {
+ case rqst.WebKMSAuth.Capability != "": // zcap ld signing
if conf.WebKMSAuthzProvider == nil {
return nil, fmt.Errorf("authorization capability for WebKMS is not configured")
}
@@ -1034,9 +1035,15 @@ func prepareUnlockOptions(rqst *UnlockWalletRequest, conf *Config) ([]wallet.Unl
webKMSHeader = func(req *http.Request) (*http.Header, error) {
return signer.SignHeader(req, []byte(rqst.WebKMSAuth.Capability))
}
- } else if rqst.WebKMSAuth.AuthToken != "" { // auth token
+ case rqst.WebKMSAuth.AuthToken != "": // auth token
webKMSHeader = func(req *http.Request) (*http.Header, error) {
- req.Header.Set("authorization", fmt.Sprintf("Bearer %s", rqst.EDVUnlock.AuthToken))
+ req.Header.Set("authorization", fmt.Sprintf("Bearer %s", rqst.WebKMSAuth.AuthToken))
+
+ return &req.Header, nil
+ }
+ case rqst.WebKMSAuth.GNAPToken != "": // GNAP token
+ webKMSHeader = func(req *http.Request) (*http.Header, error) {
+ req.Header.Set("authorization", fmt.Sprintf("GNAP %s", rqst.WebKMSAuth.GNAPToken))
return &req.Header, nil
}
@@ -1054,7 +1061,8 @@ func prepareUnlockOptions(rqst *UnlockWalletRequest, conf *Config) ([]wallet.Unl
if rqst.EDVUnlock != nil {
var edvHeader func(*http.Request) (*http.Header, error)
- if rqst.EDVUnlock.Capability != "" { // zcap ld signing
+ switch {
+ case rqst.EDVUnlock.Capability != "": // zcap ld signing
if conf.EdvAuthzProvider == nil {
return nil, fmt.Errorf("authorization capability for EDV is not configured")
}
@@ -1065,10 +1073,16 @@ func prepareUnlockOptions(rqst *UnlockWalletRequest, conf *Config) ([]wallet.Unl
edvHeader = func(req *http.Request) (*http.Header, error) {
return signer.SignHeader(req, []byte(rqst.EDVUnlock.Capability))
}
- } else if rqst.EDVUnlock.AuthToken != "" { // auth token
+ case rqst.EDVUnlock.AuthToken != "": // auth token
edvHeader = func(req *http.Request) (*http.Header, error) {
req.Header.Set("authorization", fmt.Sprintf("Bearer %s", rqst.EDVUnlock.AuthToken))
+ return &req.Header, nil
+ }
+ case rqst.EDVUnlock.GNAPToken != "": // GNAP token
+ edvHeader = func(req *http.Request) (*http.Header, error) {
+ req.Header.Set("authorization", fmt.Sprintf("GNAP %s", rqst.EDVUnlock.GNAPToken))
+
return &req.Header, nil
}
}
diff --git a/pkg/controller/command/vcwallet/models.go b/pkg/controller/command/vcwallet/models.go
index e690270b0..030948d0b 100644
--- a/pkg/controller/command/vcwallet/models.go
+++ b/pkg/controller/command/vcwallet/models.go
@@ -81,6 +81,10 @@ type UnlockAuth struct {
// Optional, only if required by wallet user (for webkms or edv).
AuthToken string `json:"authToken,omitempty"`
+ // Http header 'authorization' GNAP token to be used.
+ // Optional, only if required by wallet user (for webkms or edv).
+ GNAPToken string `json:"gnapToken,omitempty"`
+
// Capability if ZCAP sign header feature to be used for authorizing access.
// Optional, can be used only if ZCAP sign header feature is configured with command controller.
Capability string `json:"capability,omitempty"`
From 15a4bb4d88319611d3f03ee2d556c6e1272de85c Mon Sep 17 00:00:00 2001
From: Volodymyr Kubiv <62515092+vkubiv@users.noreply.github.com>
Date: Tue, 12 Jul 2022 16:41:28 +0300
Subject: [PATCH 50/54] refactor: separate didcomm from wallet. (#3264)
Signed-off-by: Volodymyr Kubiv
---
pkg/client/vcwallet/client.go | 22 +-
pkg/controller/command/vcwallet/command.go | 45 +-
pkg/wallet/didcomm.go | 665 +++++++
pkg/wallet/didcomm_test.go | 1880 +++++++++++++++++++
pkg/wallet/wallet.go | 644 +------
pkg/wallet/wallet_test.go | 1943 ++------------------
6 files changed, 2741 insertions(+), 2458 deletions(-)
create mode 100644 pkg/wallet/didcomm.go
create mode 100644 pkg/wallet/didcomm_test.go
diff --git a/pkg/client/vcwallet/client.go b/pkg/client/vcwallet/client.go
index efbe1024a..152e6328f 100644
--- a/pkg/client/vcwallet/client.go
+++ b/pkg/client/vcwallet/client.go
@@ -62,8 +62,9 @@ var noAuth walletAuth = func() (string, error) { return "", ErrWalletLocked }
// Client enable access to verifiable credential wallet features.
type Client struct {
- wallet *wallet.Wallet
- auth walletAuth
+ wallet *wallet.Wallet
+ didComm *wallet.DidComm
+ auth walletAuth
}
// New returns new verifiable credential wallet client for given user.
@@ -83,7 +84,12 @@ func New(userID string, ctx provider, options ...wallet.UnlockOptions) (*Client,
return nil, err
}
- client := &Client{wallet: w, auth: noAuth}
+ didComm, err := wallet.NewDidComm(w, ctx)
+ if err != nil {
+ return nil, err
+ }
+
+ client := &Client{wallet: w, didComm: didComm, auth: noAuth}
if len(options) > 0 {
if client.Close() {
@@ -370,7 +376,7 @@ func (c *Client) Connect(invitation *outofband.Invitation, options ...wallet.Con
return "", err
}
- return c.wallet.Connect(auth, invitation, options...)
+ return c.didComm.Connect(auth, invitation, options...)
}
// ProposePresentation accepts out-of-band invitation and sends message proposing presentation
@@ -395,7 +401,7 @@ func (c *Client) ProposePresentation(invitation *wallet.GenericInvitation, optio
return nil, err
}
- return c.wallet.ProposePresentation(auth, invitation, options...)
+ return c.didComm.ProposePresentation(auth, invitation, options...)
}
// PresentProof sends message present proof message from wallet to relying party.
@@ -418,7 +424,7 @@ func (c *Client) PresentProof(thID string, presentProofFrom ...wallet.ConcludeIn
return nil, err
}
- return c.wallet.PresentProof(auth, thID, presentProofFrom...)
+ return c.didComm.PresentProof(auth, thID, presentProofFrom...)
}
// ProposeCredential sends propose credential message from wallet to issuer.
@@ -441,7 +447,7 @@ func (c *Client) ProposeCredential(invitation *wallet.GenericInvitation, options
return nil, err
}
- return c.wallet.ProposeCredential(auth, invitation, options...)
+ return c.didComm.ProposeCredential(auth, invitation, options...)
}
// RequestCredential sends request credential message from wallet to issuer and
@@ -465,7 +471,7 @@ func (c *Client) RequestCredential(thID string, options ...wallet.ConcludeIntera
return nil, err
}
- return c.wallet.RequestCredential(auth, thID, options...)
+ return c.didComm.RequestCredential(auth, thID, options...)
}
// ResolveCredentialManifest resolves given credential manifest by credential fulfillment or credential.
diff --git a/pkg/controller/command/vcwallet/command.go b/pkg/controller/command/vcwallet/command.go
index 429dbf07a..3b618c42e 100644
--- a/pkg/controller/command/vcwallet/command.go
+++ b/pkg/controller/command/vcwallet/command.go
@@ -761,7 +761,14 @@ func (o *Command) Connect(rw io.Writer, req io.Reader) command.Error {
return command.NewExecuteError(DIDConnectErrorCode, err)
}
- connectionID, err := vcWallet.Connect(request.Auth, request.Invitation,
+ didComm, err := wallet.NewDidComm(vcWallet, o.ctx)
+ if err != nil {
+ logutil.LogInfo(logger, CommandName, ConnectMethod, err.Error())
+
+ return command.NewExecuteError(DIDConnectErrorCode, err)
+ }
+
+ connectionID, err := didComm.Connect(request.Auth, request.Invitation,
wallet.WithConnectTimeout(request.Timeout), wallet.WithReuseDID(request.ReuseConnection),
wallet.WithReuseAnyConnection(request.ReuseAnyConnection), wallet.WithMyLabel(request.MyLabel),
wallet.WithRouterConnections(request.RouterConnections...))
@@ -805,7 +812,14 @@ func (o *Command) ProposePresentation(rw io.Writer, req io.Reader) command.Error
return command.NewExecuteError(ProposePresentationErrorCode, err)
}
- msg, err := vcWallet.ProposePresentation(request.Auth, request.Invitation,
+ didComm, err := wallet.NewDidComm(vcWallet, o.ctx)
+ if err != nil {
+ logutil.LogInfo(logger, CommandName, ProposePresentationMethod, err.Error())
+
+ return command.NewExecuteError(ProposePresentationErrorCode, err)
+ }
+
+ msg, err := didComm.ProposePresentation(request.Auth, request.Invitation,
wallet.WithFromDID(request.FromDID), wallet.WithInitiateTimeout(request.Timeout),
wallet.WithConnectOptions(wallet.WithConnectTimeout(request.ConnectionOpts.Timeout),
wallet.WithReuseDID(request.ConnectionOpts.ReuseConnection),
@@ -849,7 +863,14 @@ func (o *Command) PresentProof(rw io.Writer, req io.Reader) command.Error {
return command.NewExecuteError(PresentProofErrorCode, err)
}
- status, err := vcWallet.PresentProof(request.Auth, request.ThreadID,
+ didComm, err := wallet.NewDidComm(vcWallet, o.ctx)
+ if err != nil {
+ logutil.LogInfo(logger, CommandName, PresentProofMethod, err.Error())
+
+ return command.NewExecuteError(PresentProofErrorCode, err)
+ }
+
+ status, err := didComm.PresentProof(request.Auth, request.ThreadID,
prepareConcludeInteractionOpts(request.WaitForDone, request.Timeout, request.Presentation)...)
if err != nil {
logutil.LogInfo(logger, CommandName, PresentProofMethod, err.Error())
@@ -888,7 +909,14 @@ func (o *Command) ProposeCredential(rw io.Writer, req io.Reader) command.Error {
return command.NewExecuteError(ProposeCredentialErrorCode, err)
}
- msg, err := vcWallet.ProposeCredential(request.Auth, request.Invitation,
+ didComm, err := wallet.NewDidComm(vcWallet, o.ctx)
+ if err != nil {
+ logutil.LogInfo(logger, CommandName, ProposeCredentialMethod, err.Error())
+
+ return command.NewExecuteError(ProposeCredentialErrorCode, err)
+ }
+
+ msg, err := didComm.ProposeCredential(request.Auth, request.Invitation,
wallet.WithFromDID(request.FromDID), wallet.WithInitiateTimeout(request.Timeout),
wallet.WithConnectOptions(wallet.WithConnectTimeout(request.ConnectionOpts.Timeout),
wallet.WithReuseDID(request.ConnectionOpts.ReuseConnection),
@@ -933,7 +961,14 @@ func (o *Command) RequestCredential(rw io.Writer, req io.Reader) command.Error {
return command.NewExecuteError(RequestCredentialErrorCode, err)
}
- status, err := vcWallet.RequestCredential(request.Auth, request.ThreadID,
+ didComm, err := wallet.NewDidComm(vcWallet, o.ctx)
+ if err != nil {
+ logutil.LogInfo(logger, CommandName, RequestCredentialMethod, err.Error())
+
+ return command.NewExecuteError(RequestCredentialErrorCode, err)
+ }
+
+ status, err := didComm.RequestCredential(request.Auth, request.ThreadID,
prepareConcludeInteractionOpts(request.WaitForDone, request.Timeout, request.Presentation)...)
if err != nil {
logutil.LogInfo(logger, CommandName, RequestCredentialMethod, err.Error())
diff --git a/pkg/wallet/didcomm.go b/pkg/wallet/didcomm.go
new file mode 100644
index 000000000..3c14da862
--- /dev/null
+++ b/pkg/wallet/didcomm.go
@@ -0,0 +1,665 @@
+/*
+Copyright SecureKey Technologies Inc. All Rights Reserved.
+
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package wallet
+
+import (
+ "context"
+ "fmt"
+ "time"
+
+ "github.com/google/uuid"
+
+ "github.com/hyperledger/aries-framework-go/pkg/client/didexchange"
+ "github.com/hyperledger/aries-framework-go/pkg/client/issuecredential"
+ "github.com/hyperledger/aries-framework-go/pkg/client/outofband"
+ "github.com/hyperledger/aries-framework-go/pkg/client/outofbandv2"
+ "github.com/hyperledger/aries-framework-go/pkg/client/presentproof"
+ "github.com/hyperledger/aries-framework-go/pkg/didcomm/common/model"
+ "github.com/hyperledger/aries-framework-go/pkg/didcomm/common/service"
+ "github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/decorator"
+ didexchangeSvc "github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/didexchange"
+ issuecredentialsvc "github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/issuecredential"
+ outofbandv2svc "github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/outofbandv2"
+ "github.com/hyperledger/aries-framework-go/pkg/kms"
+ "github.com/hyperledger/aries-framework-go/pkg/store/connection"
+ "github.com/hyperledger/aries-framework-go/spi/storage"
+)
+
+// miscellaneous constants.
+const (
+ msgEventBufferSize = 10
+ ldJSONMimeType = "application/ld+json"
+
+ // protocol states.
+ stateNameAbandoned = "abandoned"
+ stateNameAbandoning = "abandoning"
+ stateNameDone = "done"
+
+ // timeout constants.
+ defaultDIDExchangeTimeOut = 120 * time.Second
+ defaultWaitForRequestPresentationTimeOut = 120 * time.Second
+ defaultWaitForPresentProofDone = 120 * time.Second
+ retryDelay = 500 * time.Millisecond
+)
+
+// didCommProvider to be used only if wallet needs to be participated in DIDComm operation.
+// TODO: using wallet KMS instead of provider KMS.
+// TODO: reconcile Protocol storage with wallet store.
+type didCommProvider interface {
+ KMS() kms.KeyManager
+ ServiceEndpoint() string
+ ProtocolStateStorageProvider() storage.Provider
+ Service(id string) (interface{}, error)
+ KeyType() kms.KeyType
+ KeyAgreementType() kms.KeyType
+}
+
+type combinedDidCommWalletProvider interface {
+ provider
+ didCommProvider
+}
+
+// DidComm enables access to verifiable credential wallet features.
+type DidComm struct {
+ // wallet implementation
+ wallet *Wallet
+
+ // present proof client
+ presentProofClient *presentproof.Client
+
+ // issue credential client
+ issueCredentialClient *issuecredential.Client
+
+ // out of band client
+ oobClient *outofband.Client
+
+ // out of band v2 client
+ oobV2Client *outofbandv2.Client
+
+ // did-exchange client
+ didexchangeClient *didexchange.Client
+
+ // connection lookup
+ connectionLookup *connection.Lookup
+}
+
+// NewDidComm returns new verifiable credential wallet for given user.
+// returns error if wallet profile is not found.
+// To create a new wallet profile, use `CreateProfile()`.
+// To update an existing profile, use `UpdateProfile()`.
+func NewDidComm(wallet *Wallet, ctx combinedDidCommWalletProvider) (*DidComm, error) {
+ presentProofClient, err := presentproof.New(ctx)
+ if err != nil {
+ return nil, fmt.Errorf("failed to initialize present proof client: %w", err)
+ }
+
+ issueCredentialClient, err := issuecredential.New(ctx)
+ if err != nil {
+ return nil, fmt.Errorf("failed to initialize issue credential client: %w", err)
+ }
+
+ oobClient, err := outofband.New(ctx)
+ if err != nil {
+ return nil, fmt.Errorf("failed to initialize out-of-band client: %w", err)
+ }
+
+ oobV2Client, err := outofbandv2.New(ctx)
+ if err != nil {
+ return nil, fmt.Errorf("failed to initialize out-of-band v2 client: %w", err)
+ }
+
+ connectionLookup, err := connection.NewLookup(ctx)
+ if err != nil {
+ return nil, fmt.Errorf("failed to initialize connection lookup: %w", err)
+ }
+
+ didexchangeClient, err := didexchange.New(ctx)
+ if err != nil {
+ return nil, fmt.Errorf("failed to initialize didexchange client: %w", err)
+ }
+
+ return &DidComm{
+ wallet: wallet,
+ presentProofClient: presentProofClient,
+ issueCredentialClient: issueCredentialClient,
+ oobClient: oobClient,
+ oobV2Client: oobV2Client,
+ didexchangeClient: didexchangeClient,
+ connectionLookup: connectionLookup,
+ }, nil
+}
+
+// Connect accepts out-of-band invitations and performs DID exchange.
+//
+// Args:
+// - authToken: authorization for performing create key pair operation.
+// - invitation: out-of-band invitation.
+// - options: connection options.
+//
+// Returns:
+// - connection ID if DID exchange is successful.
+// - error if operation false.
+//
+func (c *DidComm) Connect(authToken string, invitation *outofband.Invitation, options ...ConnectOptions) (string, error) { //nolint: lll
+ statusCh := make(chan service.StateMsg, msgEventBufferSize)
+
+ err := c.didexchangeClient.RegisterMsgEvent(statusCh)
+ if err != nil {
+ return "", fmt.Errorf("failed to register msg event : %w", err)
+ }
+
+ defer func() {
+ e := c.didexchangeClient.UnregisterMsgEvent(statusCh)
+ if e != nil {
+ logger.Warnf("Failed to unregister msg event for connect: %w", e)
+ }
+ }()
+
+ opts := &connectOpts{}
+ for _, opt := range options {
+ opt(opts)
+ }
+
+ connID, err := c.oobClient.AcceptInvitation(invitation, opts.Label, getOobMessageOptions(opts)...)
+ if err != nil {
+ return "", fmt.Errorf("failed to accept invitation : %w", err)
+ }
+
+ if opts.timeout == 0 {
+ opts.timeout = defaultDIDExchangeTimeOut
+ }
+
+ ctx, cancel := context.WithTimeout(context.Background(), opts.timeout)
+ defer cancel()
+
+ err = waitForConnect(ctx, statusCh, connID)
+ if err != nil {
+ return "", fmt.Errorf("wallet connect failed : %w", err)
+ }
+
+ return connID, nil
+}
+
+// ProposePresentation accepts out-of-band invitation and sends message proposing presentation
+// from wallet to relying party.
+// https://w3c-ccg.github.io/universal-wallet-interop-spec/#proposepresentation
+//
+// Currently Supporting
+// [0454-present-proof-v2](https://github.com/hyperledger/aries-rfcs/tree/master/features/0454-present-proof-v2)
+//
+// Args:
+// - authToken: authorization for performing operation.
+// - invitation: out-of-band invitation from relying party.
+// - options: options for accepting invitation and send propose presentation message.
+//
+// Returns:
+// - DIDCommMsgMap containing request presentation message if operation is successful.
+// - error if operation fails.
+//
+func (c *DidComm) ProposePresentation(authToken string, invitation *GenericInvitation, options ...InitiateInteractionOption) (*service.DIDCommMsgMap, error) { //nolint: lll
+ opts := &initiateInteractionOpts{}
+ for _, opt := range options {
+ opt(opts)
+ }
+
+ var (
+ connID string
+ err error
+ )
+
+ switch invitation.Version() {
+ default:
+ fallthrough
+ case service.V1:
+ connID, err = c.Connect(authToken, (*outofband.Invitation)(invitation.AsV1()), opts.connectOpts...)
+ if err != nil {
+ return nil, fmt.Errorf("failed to perform did connection : %w", err)
+ }
+ case service.V2:
+ connOpts := &connectOpts{}
+
+ for _, opt := range opts.connectOpts {
+ opt(connOpts)
+ }
+
+ connID, err = c.oobV2Client.AcceptInvitation(
+ invitation.AsV2(),
+ outofbandv2svc.WithRouterConnections(connOpts.Connections),
+ )
+ if err != nil {
+ return nil, fmt.Errorf("failed to accept OOB v2 invitation : %w", err)
+ }
+ }
+
+ connRecord, err := c.connectionLookup.GetConnectionRecord(connID)
+ if err != nil {
+ return nil, fmt.Errorf("failed to lookup connection for propose presentation : %w", err)
+ }
+
+ opts = prepareInteractionOpts(connRecord, opts)
+
+ _, err = c.presentProofClient.SendProposePresentation(&presentproof.ProposePresentation{}, connRecord)
+ if err != nil {
+ return nil, fmt.Errorf("failed to propose presentation from wallet: %w", err)
+ }
+
+ ctx, cancel := context.WithTimeout(context.Background(), opts.timeout)
+ defer cancel()
+
+ return c.waitForRequestPresentation(ctx, connRecord)
+}
+
+// PresentProof sends message present proof message from wallet to relying party.
+// https://w3c-ccg.github.io/universal-wallet-interop-spec/#presentproof
+//
+// Currently Supporting
+// [0454-present-proof-v2](https://github.com/hyperledger/aries-rfcs/tree/master/features/0454-present-proof-v2)
+//
+// Args:
+// - authToken: authorization for performing operation.
+// - thID: thread ID (action ID) of request presentation.
+// - presentProofFrom: presentation to be sent.
+//
+// Returns:
+// - Credential interaction status containing status, redirectURL.
+// - error if operation fails.
+//
+func (c *DidComm) PresentProof(authToken, thID string, options ...ConcludeInteractionOptions) (*CredentialInteractionStatus, error) { //nolint: lll
+ opts := &concludeInteractionOpts{}
+
+ for _, option := range options {
+ option(opts)
+ }
+
+ var presentation interface{}
+ if opts.presentation != nil {
+ presentation = opts.presentation
+ } else {
+ presentation = opts.rawPresentation
+ }
+
+ err := c.presentProofClient.AcceptRequestPresentation(thID, &presentproof.Presentation{
+ Attachments: []decorator.GenericAttachment{{
+ ID: uuid.New().String(),
+ Data: decorator.AttachmentData{
+ JSON: presentation,
+ },
+ }},
+ }, nil)
+ if err != nil {
+ return nil, err
+ }
+
+ // wait for ack or problem-report.
+ if opts.waitForDone {
+ statusCh := make(chan service.StateMsg, msgEventBufferSize)
+
+ err = c.presentProofClient.RegisterMsgEvent(statusCh)
+ if err != nil {
+ return nil, fmt.Errorf("failed to register present proof msg event : %w", err)
+ }
+
+ defer func() {
+ e := c.presentProofClient.UnregisterMsgEvent(statusCh)
+ if e != nil {
+ logger.Warnf("Failed to unregister msg event for present proof: %w", e)
+ }
+ }()
+
+ ctx, cancel := context.WithTimeout(context.Background(), opts.timeout)
+ defer cancel()
+
+ return waitCredInteractionCompletion(ctx, statusCh, thID)
+ }
+
+ return &CredentialInteractionStatus{Status: model.AckStatusPENDING}, nil
+}
+
+// ProposeCredential sends propose credential message from wallet to issuer.
+// https://w3c-ccg.github.io/universal-wallet-interop-spec/#proposecredential
+//
+// Currently Supporting : 0453-issueCredentialV2
+// https://github.com/hyperledger/aries-rfcs/blob/main/features/0453-issue-credential-v2/README.md
+//
+// Args:
+// - authToken: authorization for performing operation.
+// - invitation: out-of-band invitation from issuer.
+// - options: options for accepting invitation and send propose credential message.
+//
+// Returns:
+// - DIDCommMsgMap containing offer credential message if operation is successful.
+// - error if operation fails.
+//
+func (c *DidComm) ProposeCredential(authToken string, invitation *GenericInvitation, options ...InitiateInteractionOption) (*service.DIDCommMsgMap, error) { //nolint: lll
+ opts := &initiateInteractionOpts{}
+ for _, opt := range options {
+ opt(opts)
+ }
+
+ var (
+ connID string
+ err error
+ )
+
+ switch invitation.Version() {
+ default:
+ fallthrough
+ case service.V1:
+ connID, err = c.Connect(authToken, (*outofband.Invitation)(invitation.AsV1()), opts.connectOpts...)
+ if err != nil {
+ return nil, fmt.Errorf("failed to perform did connection : %w", err)
+ }
+ case service.V2:
+ connOpts := &connectOpts{}
+
+ for _, opt := range opts.connectOpts {
+ opt(connOpts)
+ }
+
+ connID, err = c.oobV2Client.AcceptInvitation(
+ invitation.AsV2(),
+ outofbandv2svc.WithRouterConnections(connOpts.Connections),
+ )
+ if err != nil {
+ return nil, fmt.Errorf("failed to accept OOB v2 invitation : %w", err)
+ }
+ }
+
+ connRecord, err := c.connectionLookup.GetConnectionRecord(connID)
+ if err != nil {
+ return nil, fmt.Errorf("failed to lookup connection for propose presentation : %w", err)
+ }
+
+ opts = prepareInteractionOpts(connRecord, opts)
+
+ _, err = c.issueCredentialClient.SendProposal(
+ &issuecredential.ProposeCredential{InvitationID: invitation.ID},
+ connRecord,
+ )
+ if err != nil {
+ return nil, fmt.Errorf("failed to propose credential from wallet: %w", err)
+ }
+
+ ctx, cancel := context.WithTimeout(context.Background(), opts.timeout)
+ defer cancel()
+
+ return c.waitForOfferCredential(ctx, connRecord)
+}
+
+// RequestCredential sends request credential message from wallet to issuer and
+// optionally waits for credential fulfillment.
+// https://w3c-ccg.github.io/universal-wallet-interop-spec/#requestcredential
+//
+// Currently Supporting : 0453-issueCredentialV2
+// https://github.com/hyperledger/aries-rfcs/blob/main/features/0453-issue-credential-v2/README.md
+//
+// Args:
+// - authToken: authorization for performing operation.
+// - thID: thread ID (action ID) of offer credential message previously received.
+// - concludeInteractionOptions: options to conclude interaction like presentation to be shared etc.
+//
+// Returns:
+// - Credential interaction status containing status, redirectURL.
+// - error if operation fails.
+//
+func (c *DidComm) RequestCredential(authToken, thID string, options ...ConcludeInteractionOptions) (*CredentialInteractionStatus, error) { //nolint: lll
+ opts := &concludeInteractionOpts{}
+
+ for _, option := range options {
+ option(opts)
+ }
+
+ var presentation interface{}
+ if opts.presentation != nil {
+ presentation = opts.presentation
+ } else {
+ presentation = opts.rawPresentation
+ }
+
+ attachmentID := uuid.New().String()
+
+ err := c.issueCredentialClient.AcceptOffer(thID, &issuecredential.RequestCredential{
+ Type: issuecredentialsvc.RequestCredentialMsgTypeV2,
+ Formats: []issuecredentialsvc.Format{{
+ AttachID: attachmentID,
+ Format: ldJSONMimeType,
+ }},
+ Attachments: []decorator.GenericAttachment{{
+ ID: attachmentID,
+ Data: decorator.AttachmentData{
+ JSON: presentation,
+ },
+ }},
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ // wait for credential fulfillment.
+ if opts.waitForDone {
+ statusCh := make(chan service.StateMsg, msgEventBufferSize)
+
+ err = c.issueCredentialClient.RegisterMsgEvent(statusCh)
+ if err != nil {
+ return nil, fmt.Errorf("failed to register issue credential action event : %w", err)
+ }
+
+ defer func() {
+ e := c.issueCredentialClient.UnregisterMsgEvent(statusCh)
+ if e != nil {
+ logger.Warnf("Failed to unregister action event for issue credential: %w", e)
+ }
+ }()
+
+ ctx, cancel := context.WithTimeout(context.Background(), opts.timeout)
+ defer cancel()
+
+ return waitCredInteractionCompletion(ctx, statusCh, thID)
+ }
+
+ return &CredentialInteractionStatus{Status: model.AckStatusPENDING}, nil
+}
+
+// currently correlating response action by connection due to limitation in current present proof V1 implementation.
+func (c *DidComm) waitForRequestPresentation(ctx context.Context, record *connection.Record) (*service.DIDCommMsgMap, error) { //nolint: lll
+ done := make(chan *service.DIDCommMsgMap)
+
+ go func() {
+ for {
+ actions, err := c.presentProofClient.Actions()
+ if err != nil {
+ continue
+ }
+
+ if len(actions) > 0 {
+ for _, action := range actions {
+ if action.MyDID == record.MyDID && action.TheirDID == record.TheirDID {
+ done <- &action.Msg
+ return
+ }
+ }
+ }
+
+ select {
+ default:
+ time.Sleep(retryDelay)
+ case <-ctx.Done():
+ return
+ }
+ }
+ }()
+
+ select {
+ case msg := <-done:
+ return msg, nil
+ case <-ctx.Done():
+ return nil, fmt.Errorf("timeout waiting for request presentation message")
+ }
+}
+
+// currently correlating response action by connection due to limitation in current issue credential V1 implementation.
+func (c *DidComm) waitForOfferCredential(ctx context.Context, record *connection.Record) (*service.DIDCommMsgMap, error) { //nolint: lll
+ done := make(chan *service.DIDCommMsgMap)
+
+ go func() {
+ for {
+ actions, err := c.issueCredentialClient.Actions()
+ if err != nil {
+ continue
+ }
+
+ if len(actions) > 0 {
+ for _, action := range actions {
+ if action.MyDID == record.MyDID && action.TheirDID == record.TheirDID {
+ done <- &action.Msg
+ return
+ }
+ }
+ }
+
+ select {
+ default:
+ time.Sleep(retryDelay)
+ case <-ctx.Done():
+ return
+ }
+ }
+ }()
+
+ select {
+ case msg := <-done:
+ return msg, nil
+ case <-ctx.Done():
+ return nil, fmt.Errorf("timeout waiting for offer credential message")
+ }
+}
+
+func waitForConnect(ctx context.Context, didStateMsgs chan service.StateMsg, connID string) error {
+ done := make(chan struct{})
+
+ go func() {
+ for msg := range didStateMsgs {
+ if msg.Type != service.PostState || msg.StateID != didexchangeSvc.StateIDCompleted {
+ continue
+ }
+
+ var event didexchangeSvc.Event
+
+ switch p := msg.Properties.(type) {
+ case didexchangeSvc.Event:
+ event = p
+ default:
+ logger.Warnf("failed to cast didexchange event properties")
+
+ continue
+ }
+
+ if event.ConnectionID() == connID {
+ logger.Debugf(
+ "Received connection complete event for invitationID=%s connectionID=%s",
+ event.InvitationID(), event.ConnectionID())
+
+ close(done)
+
+ break
+ }
+ }
+ }()
+
+ select {
+ case <-done:
+ return nil
+ case <-ctx.Done():
+ return fmt.Errorf("time out waiting for did exchange state 'completed'")
+ }
+}
+
+// wait for credential interaction to be completed (done or abandoned protocol state).
+func waitCredInteractionCompletion(ctx context.Context, didStateMsgs chan service.StateMsg, thID string) (*CredentialInteractionStatus, error) { // nolint:gocognit,gocyclo,lll
+ done := make(chan *CredentialInteractionStatus)
+
+ go func() {
+ for msg := range didStateMsgs {
+ // match post state.
+ if msg.Type != service.PostState {
+ continue
+ }
+
+ // invalid state msg.
+ if msg.Msg == nil {
+ continue
+ }
+
+ msgThID, err := msg.Msg.ThreadID()
+ if err != nil {
+ continue
+ }
+
+ // match parent thread ID.
+ if msg.Msg.ParentThreadID() != thID && msgThID != thID {
+ continue
+ }
+
+ // match protocol state.
+ if msg.StateID != stateNameDone && msg.StateID != stateNameAbandoned && msg.StateID != stateNameAbandoning {
+ continue
+ }
+
+ properties := msg.Properties.All()
+
+ response := &CredentialInteractionStatus{}
+ response.RedirectURL, response.Status = getWebRedirectInfo(properties)
+
+ // if redirect status missing, then use protocol state, done -> OK, abandoned -> FAIL.
+ if response.Status == "" {
+ if msg.StateID == stateNameAbandoned || msg.StateID == stateNameAbandoning {
+ response.Status = model.AckStatusFAIL
+ } else {
+ response.Status = model.AckStatusOK
+ }
+ }
+
+ done <- response
+
+ return
+ }
+ }()
+
+ select {
+ case status := <-done:
+ return status, nil
+ case <-ctx.Done():
+ return nil, fmt.Errorf("time out waiting for credential interaction to get completed")
+ }
+}
+
+func prepareInteractionOpts(connRecord *connection.Record, opts *initiateInteractionOpts) *initiateInteractionOpts {
+ if opts.from == "" {
+ opts.from = connRecord.TheirDID
+ }
+
+ if opts.timeout == 0 {
+ opts.timeout = defaultWaitForRequestPresentationTimeOut
+ }
+
+ return opts
+}
+
+// getWebRedirectInfo reads web redirect info from properties.
+func getWebRedirectInfo(properties map[string]interface{}) (string, string) {
+ var redirect, status string
+
+ if redirectURL, ok := properties[webRedirectURLKey]; ok {
+ redirect = redirectURL.(string) //nolint: errcheck, forcetypeassert
+ }
+
+ if redirectStatus, ok := properties[webRedirectStatusKey]; ok {
+ status = redirectStatus.(string) //nolint: errcheck, forcetypeassert
+ }
+
+ return redirect, status
+}
diff --git a/pkg/wallet/didcomm_test.go b/pkg/wallet/didcomm_test.go
new file mode 100644
index 000000000..b0ab7ca0d
--- /dev/null
+++ b/pkg/wallet/didcomm_test.go
@@ -0,0 +1,1880 @@
+/*
+Copyright SecureKey Technologies Inc. All Rights Reserved.
+
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package wallet
+
+import (
+ _ "embed"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "testing"
+ "time"
+
+ "github.com/golang/mock/gomock"
+ "github.com/google/uuid"
+ "github.com/stretchr/testify/require"
+
+ "github.com/hyperledger/aries-framework-go/pkg/client/outofband"
+ "github.com/hyperledger/aries-framework-go/pkg/didcomm/common/model"
+ "github.com/hyperledger/aries-framework-go/pkg/didcomm/common/service"
+ "github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/didexchange"
+ issuecredentialsvc "github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/issuecredential"
+ "github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/mediator"
+ outofbandSvc "github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/outofband"
+ oobv2 "github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/outofbandv2"
+ presentproofSvc "github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/presentproof"
+ "github.com/hyperledger/aries-framework-go/pkg/doc/verifiable"
+ mockoutofbandv2 "github.com/hyperledger/aries-framework-go/pkg/internal/gomocks/client/outofbandv2"
+ "github.com/hyperledger/aries-framework-go/pkg/internal/ldtestutil"
+ mockdidexchange "github.com/hyperledger/aries-framework-go/pkg/mock/didcomm/protocol/didexchange"
+ mockissuecredential "github.com/hyperledger/aries-framework-go/pkg/mock/didcomm/protocol/issuecredential"
+ mockmediator "github.com/hyperledger/aries-framework-go/pkg/mock/didcomm/protocol/mediator"
+ mockoutofband "github.com/hyperledger/aries-framework-go/pkg/mock/didcomm/protocol/outofband"
+ mockpresentproof "github.com/hyperledger/aries-framework-go/pkg/mock/didcomm/protocol/presentproof"
+ mockprovider "github.com/hyperledger/aries-framework-go/pkg/mock/provider"
+ mockstorage "github.com/hyperledger/aries-framework-go/pkg/mock/storage"
+ "github.com/hyperledger/aries-framework-go/pkg/store/connection"
+)
+
+const (
+ exampleWebRedirect = "http://example.com/sample"
+ sampleMsgComment = "sample mock msg"
+)
+
+func TestNewDidComm(t *testing.T) {
+ t.Run("test get wallet failure - present proof client initialize error", func(t *testing.T) {
+ mockctx := newDidCommMockProvider(t)
+ delete(mockctx.ServiceMap, presentproofSvc.Name)
+
+ err := CreateProfile(sampleUserID, mockctx, WithPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+
+ wallet, err := New(sampleUserID, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, wallet)
+
+ didcomm, err := NewDidComm(wallet, mockctx)
+ require.Error(t, err)
+ require.Empty(t, didcomm)
+
+ require.Contains(t, err.Error(), "failed to initialize present proof client")
+ })
+
+ t.Run("test get wallet failure - oob client initialize error", func(t *testing.T) {
+ mockctx := newDidCommMockProvider(t)
+ delete(mockctx.ServiceMap, outofbandSvc.Name)
+
+ err := CreateProfile(sampleUserID, mockctx, WithPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+
+ wallet, err := New(sampleUserID, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, wallet)
+
+ didcomm, err := NewDidComm(wallet, mockctx)
+ require.Error(t, err)
+ require.Empty(t, didcomm)
+ require.Contains(t, err.Error(), "failed to initialize out-of-band client")
+ })
+
+ t.Run("test get wallet failure - oob client initialize error", func(t *testing.T) {
+ mockctx := newDidCommMockProvider(t)
+ delete(mockctx.ServiceMap, didexchange.DIDExchange)
+
+ err := CreateProfile(sampleUserID, mockctx, WithPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+
+ wallet, err := New(sampleUserID, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, wallet)
+
+ didcomm, err := NewDidComm(wallet, mockctx)
+ require.Error(t, err)
+ require.Empty(t, didcomm)
+ require.Contains(t, err.Error(), "failed to initialize didexchange client")
+ })
+
+ t.Run("test get wallet failure - connection lookup initialize error", func(t *testing.T) {
+ mockctx := newDidCommMockProvider(t)
+ mockStoreProvider := mockstorage.NewMockStoreProvider()
+ mockStoreProvider.FailNamespace = "didexchange"
+ mockctx.StorageProviderValue = mockStoreProvider
+
+ err := CreateProfile(sampleUserID, mockctx, WithPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+
+ wallet, err := New(sampleUserID, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, wallet)
+
+ didcomm, err := NewDidComm(wallet, mockctx)
+ require.Error(t, err)
+ require.Empty(t, didcomm)
+ require.Contains(t, err.Error(), "failed to initialize connection lookup")
+ })
+}
+
+func TestWallet_Connect(t *testing.T) {
+ sampleDIDCommUser := uuid.New().String()
+ mockctx := newDidCommMockProvider(t)
+ err := CreateProfile(sampleDIDCommUser, mockctx, WithPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+
+ t.Run("test did connect success", func(t *testing.T) {
+ sampleConnID := uuid.New().String()
+
+ oobSvc := &mockoutofband.MockOobService{
+ AcceptInvitationHandle: func(*outofbandSvc.Invitation, outofbandSvc.Options) (string, error) {
+ return sampleConnID, nil
+ },
+ }
+ mockctx.ServiceMap[outofbandSvc.Name] = oobSvc
+
+ didexSvc := &mockdidexchange.MockDIDExchangeSvc{
+ RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
+ ch <- service.StateMsg{
+ Type: service.PostState,
+ StateID: didexchange.StateIDCompleted,
+ Properties: &mockdidexchange.MockEventProperties{ConnID: sampleConnID},
+ }
+
+ return nil
+ },
+ }
+ mockctx.ServiceMap[didexchange.DIDExchange] = didexSvc
+
+ wallet, err := New(sampleDIDCommUser, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, wallet)
+
+ didcomm, err := NewDidComm(wallet, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, didcomm)
+
+ token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+ require.NotEmpty(t, token)
+
+ defer wallet.Close()
+
+ connectionID, err := didcomm.Connect(token, &outofband.Invitation{})
+ require.NoError(t, err)
+ require.Equal(t, sampleConnID, connectionID)
+ })
+
+ t.Run("test did connect failure - accept invitation failure", func(t *testing.T) {
+ oobSvc := &mockoutofband.MockOobService{
+ AcceptInvitationHandle: func(*outofbandSvc.Invitation, outofbandSvc.Options) (string, error) {
+ return "", fmt.Errorf(sampleWalletErr)
+ },
+ }
+
+ mockctx.ServiceMap[outofbandSvc.Name] = oobSvc
+
+ wallet, err := New(sampleDIDCommUser, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, wallet)
+
+ didcomm, err := NewDidComm(wallet, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, didcomm)
+
+ token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+ require.NotEmpty(t, token)
+
+ defer wallet.Close()
+
+ connectionID, err := didcomm.Connect(token, &outofband.Invitation{}, WithConnectTimeout(1*time.Millisecond))
+ require.Error(t, err)
+ require.Contains(t, err.Error(), sampleWalletErr)
+ require.Contains(t, err.Error(), "failed to accept invitation")
+ require.Empty(t, connectionID)
+ })
+
+ t.Run("test did connect failure - register event failure", func(t *testing.T) {
+ didexSvc := &mockdidexchange.MockDIDExchangeSvc{
+ RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
+ return fmt.Errorf(sampleWalletErr)
+ },
+ }
+ mockctx.ServiceMap[didexchange.DIDExchange] = didexSvc
+
+ wallet, err := New(sampleDIDCommUser, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, wallet)
+
+ didcomm, err := NewDidComm(wallet, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, didcomm)
+
+ token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+ require.NotEmpty(t, token)
+
+ defer wallet.Close()
+
+ connectionID, err := didcomm.Connect(token, &outofband.Invitation{}, WithConnectTimeout(1*time.Millisecond))
+ require.Error(t, err)
+ require.Contains(t, err.Error(), sampleWalletErr)
+ require.Contains(t, err.Error(), "failed to register msg event")
+ require.Empty(t, connectionID)
+ })
+
+ t.Run("test did connect failure - state not completed", func(t *testing.T) {
+ mockctx.ServiceMap[outofbandSvc.Name] = &mockoutofband.MockOobService{}
+ mockctx.ServiceMap[didexchange.DIDExchange] = &mockdidexchange.MockDIDExchangeSvc{}
+
+ wallet, err := New(sampleDIDCommUser, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, wallet)
+
+ didcomm, err := NewDidComm(wallet, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, didcomm)
+
+ token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+ require.NotEmpty(t, token)
+
+ defer wallet.Close()
+
+ connectionID, err := didcomm.Connect(token, &outofband.Invitation{}, WithConnectTimeout(1*time.Millisecond))
+ require.Error(t, err)
+ require.Contains(t, err.Error(), "time out waiting for did exchange state 'completed'")
+ require.Empty(t, connectionID)
+ })
+
+ t.Run("test did connect success - with warnings", func(t *testing.T) {
+ sampleConnID := uuid.New().String()
+
+ oobSvc := &mockoutofband.MockOobService{
+ AcceptInvitationHandle: func(*outofbandSvc.Invitation, outofbandSvc.Options) (string, error) {
+ return sampleConnID, nil
+ },
+ }
+ mockctx.ServiceMap[outofbandSvc.Name] = oobSvc
+
+ didexSvc := &mockdidexchange.MockDIDExchangeSvc{
+ RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
+ ch <- service.StateMsg{
+ Type: service.PreState,
+ StateID: didexchange.StateIDCompleted,
+ }
+
+ ch <- service.StateMsg{
+ Type: service.PostState,
+ StateID: didexchange.StateIDCompleted,
+ }
+
+ ch <- service.StateMsg{
+ Type: service.PostState,
+ StateID: didexchange.StateIDCompleted,
+ Properties: &mockdidexchange.MockEventProperties{ConnID: sampleConnID},
+ }
+
+ return nil
+ },
+ UnregisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
+ return fmt.Errorf(sampleWalletErr)
+ },
+ }
+ mockctx.ServiceMap[didexchange.DIDExchange] = didexSvc
+
+ wallet, err := New(sampleDIDCommUser, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, wallet)
+
+ didcomm, err := NewDidComm(wallet, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, didcomm)
+
+ token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+ require.NotEmpty(t, token)
+
+ defer wallet.Close()
+
+ connectionID, err := didcomm.Connect(token, &outofband.Invitation{})
+ require.NoError(t, err)
+ require.Equal(t, sampleConnID, connectionID)
+ })
+
+ t.Run("test oob connect options", func(t *testing.T) {
+ options := []ConnectOptions{
+ WithConnectTimeout(10 * time.Second),
+ WithRouterConnections("sample-conn"),
+ WithMyLabel("sample-label"),
+ WithReuseAnyConnection(true),
+ WithReuseDID("sample-did"),
+ }
+
+ opts := &connectOpts{}
+ for _, opt := range options {
+ opt(opts)
+ }
+
+ require.Equal(t, opts.timeout, 10*time.Second)
+ require.Equal(t, opts.Connections[0], "sample-conn")
+ require.Equal(t, opts.MyLabel(), "sample-label")
+ require.Equal(t, opts.ReuseDID, "sample-did")
+ require.True(t, opts.ReuseAny)
+
+ require.Len(t, getOobMessageOptions(opts), 3)
+ })
+}
+
+func TestWallet_ProposePresentation(t *testing.T) {
+ sampleDIDCommUser := uuid.New().String()
+ mockctx := newDidCommMockProvider(t)
+ err := CreateProfile(sampleDIDCommUser, mockctx, WithPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+
+ const (
+ myDID = "did:mydid:123"
+ theirDID = "did:theirdid:123"
+ )
+
+ t.Run("test propose presentation success - didcomm v1", func(t *testing.T) {
+ sampleConnID := uuid.New().String()
+
+ oobSvc := &mockoutofband.MockOobService{
+ AcceptInvitationHandle: func(*outofbandSvc.Invitation, outofbandSvc.Options) (string, error) {
+ return sampleConnID, nil
+ },
+ }
+ mockctx.ServiceMap[outofbandSvc.Name] = oobSvc
+
+ didexSvc := &mockdidexchange.MockDIDExchangeSvc{
+ RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
+ ch <- service.StateMsg{
+ Type: service.PostState,
+ StateID: didexchange.StateIDCompleted,
+ Properties: &mockdidexchange.MockEventProperties{ConnID: sampleConnID},
+ }
+
+ return nil
+ },
+ }
+ mockctx.ServiceMap[didexchange.DIDExchange] = didexSvc
+
+ thID := uuid.New().String()
+
+ ppSvc := &mockpresentproof.MockPresentProofSvc{
+ ActionsFunc: func() ([]presentproofSvc.Action, error) {
+ return []presentproofSvc.Action{
+ {
+ PIID: thID,
+ Msg: service.NewDIDCommMsgMap(&presentproofSvc.RequestPresentationV2{
+ Comment: "mock msg",
+ }),
+ MyDID: myDID,
+ TheirDID: theirDID,
+ },
+ }, nil
+ },
+ HandleFunc: func(service.DIDCommMsg) (string, error) {
+ return thID, nil
+ },
+ }
+
+ mockctx.ServiceMap[outofbandSvc.Name] = oobSvc
+ mockctx.ServiceMap[presentproofSvc.Name] = ppSvc
+
+ store, err := mockctx.StorageProvider().OpenStore(connection.Namespace)
+ require.NoError(t, err)
+
+ record := &connection.Record{
+ ConnectionID: sampleConnID,
+ MyDID: myDID,
+ TheirDID: theirDID,
+ }
+ recordBytes, err := json.Marshal(record)
+ require.NoError(t, err)
+ require.NoError(t, store.Put(fmt.Sprintf("conn_%s", sampleConnID), recordBytes))
+
+ wallet, err := New(sampleDIDCommUser, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, wallet)
+
+ didcomm, err := NewDidComm(wallet, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, didcomm)
+
+ token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+ require.NotEmpty(t, token)
+
+ defer wallet.Close()
+
+ invitation := GenericInvitation{}
+ err = json.Unmarshal([]byte(`{
+ "@id": "abc123",
+ "@type": "https://didcomm.org/out-of-band/1.0/invitation"
+ }`), &invitation)
+ require.NoError(t, err)
+
+ msg, err := didcomm.ProposePresentation(token, &invitation,
+ WithConnectOptions(WithConnectTimeout(1*time.Millisecond)))
+ require.NoError(t, err)
+ require.NotEmpty(t, msg)
+
+ // empty invitation defaults to DIDComm v1
+ msg, err = didcomm.ProposePresentation(token, &GenericInvitation{},
+ WithConnectOptions(WithConnectTimeout(1*time.Millisecond)))
+ require.NoError(t, err)
+ require.NotEmpty(t, msg)
+
+ // invitation with unknown version defaults to DIDComm v1
+ msg, err = didcomm.ProposePresentation(token, &GenericInvitation{version: "unknown"},
+ WithConnectOptions(WithConnectTimeout(1*time.Millisecond)))
+ require.NoError(t, err)
+ require.NotEmpty(t, msg)
+ })
+
+ t.Run("test propose presentation success - didcomm v2", func(t *testing.T) {
+ sampleConnID := uuid.New().String()
+
+ ctrl := gomock.NewController(t)
+ defer ctrl.Finish()
+
+ oobv2Svc := mockoutofbandv2.NewMockOobService(ctrl)
+ oobv2Svc.EXPECT().AcceptInvitation(gomock.Any(), gomock.Any()).Return(sampleConnID, nil).AnyTimes()
+
+ mockctx.ServiceMap[oobv2.Name] = oobv2Svc
+
+ thID := uuid.New().String()
+
+ ppSvc := &mockpresentproof.MockPresentProofSvc{
+ ActionsFunc: func() ([]presentproofSvc.Action, error) {
+ return []presentproofSvc.Action{
+ {
+ PIID: thID,
+ Msg: service.NewDIDCommMsgMap(&presentproofSvc.RequestPresentationV3{
+ Body: presentproofSvc.RequestPresentationV3Body{
+ Comment: "mock msg",
+ },
+ }),
+ MyDID: myDID,
+ TheirDID: theirDID,
+ },
+ }, nil
+ },
+ HandleFunc: func(service.DIDCommMsg) (string, error) {
+ return thID, nil
+ },
+ }
+
+ mockctx.ServiceMap[presentproofSvc.Name] = ppSvc
+
+ connRec, err := connection.NewRecorder(mockctx)
+ require.NoError(t, err)
+
+ record := &connection.Record{
+ ConnectionID: sampleConnID,
+ MyDID: myDID,
+ TheirDID: theirDID,
+ DIDCommVersion: service.V2,
+ State: connection.StateNameCompleted,
+ }
+
+ err = connRec.SaveConnectionRecord(record)
+ require.NoError(t, err)
+
+ wallet, err := New(sampleDIDCommUser, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, wallet)
+
+ didcomm, err := NewDidComm(wallet, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, didcomm)
+
+ token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+ require.NotEmpty(t, token)
+
+ defer wallet.Close()
+
+ invitation := GenericInvitation{}
+ err = json.Unmarshal([]byte(`{
+ "id": "abc123",
+ "type": "https://didcomm.org/out-of-band/2.0/invitation"
+ }`), &invitation)
+ require.NoError(t, err)
+
+ msg, err := didcomm.ProposePresentation(token, &invitation,
+ WithConnectOptions(WithConnectTimeout(1*time.Millisecond)))
+ require.NoError(t, err)
+ require.NotEmpty(t, msg)
+ })
+
+ t.Run("test propose presentation failure - did connect failure", func(t *testing.T) {
+ didexSvc := &mockdidexchange.MockDIDExchangeSvc{
+ RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
+ return fmt.Errorf(sampleWalletErr)
+ },
+ }
+ mockctx.ServiceMap[didexchange.DIDExchange] = didexSvc
+
+ wallet, err := New(sampleDIDCommUser, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, wallet)
+
+ didcomm, err := NewDidComm(wallet, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, didcomm)
+
+ token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+ require.NotEmpty(t, token)
+
+ defer wallet.Close()
+
+ msg, err := didcomm.ProposePresentation(token, &GenericInvitation{})
+ require.Error(t, err)
+ require.Contains(t, err.Error(), sampleWalletErr)
+ require.Contains(t, err.Error(), "failed to perform did connection")
+ require.Empty(t, msg)
+ })
+
+ t.Run("test propose presentation failure - no connection found", func(t *testing.T) {
+ sampleConnID := uuid.New().String()
+
+ oobSvc := &mockoutofband.MockOobService{
+ AcceptInvitationHandle: func(*outofbandSvc.Invitation, outofbandSvc.Options) (string, error) {
+ return sampleConnID, nil
+ },
+ }
+ mockctx.ServiceMap[outofbandSvc.Name] = oobSvc
+
+ didexSvc := &mockdidexchange.MockDIDExchangeSvc{
+ RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
+ ch <- service.StateMsg{
+ Type: service.PostState,
+ StateID: didexchange.StateIDCompleted,
+ Properties: &mockdidexchange.MockEventProperties{ConnID: sampleConnID},
+ }
+
+ return nil
+ },
+ }
+ mockctx.ServiceMap[didexchange.DIDExchange] = didexSvc
+
+ wallet, err := New(sampleDIDCommUser, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, wallet)
+
+ didcomm, err := NewDidComm(wallet, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, didcomm)
+
+ token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+ require.NotEmpty(t, token)
+
+ defer wallet.Close()
+
+ msg, err := didcomm.ProposePresentation(token, &GenericInvitation{})
+ require.Error(t, err)
+ require.Contains(t, err.Error(), "failed to lookup connection")
+ require.Empty(t, msg)
+ })
+
+ t.Run("test propose presentation failure - failed to send", func(t *testing.T) {
+ sampleConnID := uuid.New().String()
+
+ oobSvc := &mockoutofband.MockOobService{
+ AcceptInvitationHandle: func(*outofbandSvc.Invitation, outofbandSvc.Options) (string, error) {
+ return sampleConnID, nil
+ },
+ }
+ mockctx.ServiceMap[outofbandSvc.Name] = oobSvc
+
+ didexSvc := &mockdidexchange.MockDIDExchangeSvc{
+ RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
+ ch <- service.StateMsg{
+ Type: service.PostState,
+ StateID: didexchange.StateIDCompleted,
+ Properties: &mockdidexchange.MockEventProperties{ConnID: sampleConnID},
+ }
+
+ return nil
+ },
+ }
+ mockctx.ServiceMap[didexchange.DIDExchange] = didexSvc
+
+ ppSvc := &mockpresentproof.MockPresentProofSvc{
+ HandleFunc: func(service.DIDCommMsg) (string, error) {
+ return "", fmt.Errorf(sampleWalletErr)
+ },
+ HandleOutboundFunc: func(service.DIDCommMsg, string, string) (string, error) {
+ return "", fmt.Errorf(sampleWalletErr)
+ },
+ }
+ mockctx.ServiceMap[presentproofSvc.Name] = ppSvc
+
+ store, err := mockctx.StorageProvider().OpenStore(connection.Namespace)
+ require.NoError(t, err)
+
+ record := &connection.Record{
+ ConnectionID: sampleConnID,
+ MyDID: myDID,
+ TheirDID: theirDID,
+ }
+ recordBytes, err := json.Marshal(record)
+ require.NoError(t, err)
+ require.NoError(t, store.Put(fmt.Sprintf("conn_%s", sampleConnID), recordBytes))
+
+ wallet, err := New(sampleDIDCommUser, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, wallet)
+
+ didcomm, err := NewDidComm(wallet, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, didcomm)
+
+ token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+ require.NotEmpty(t, token)
+
+ defer wallet.Close()
+
+ msg, err := didcomm.ProposePresentation(token, &GenericInvitation{})
+ require.Error(t, err)
+ require.Contains(t, err.Error(), sampleWalletErr)
+ require.Contains(t, err.Error(), "failed to propose presentation from wallet")
+ require.Empty(t, msg)
+ })
+
+ t.Run("test propose presentation failure - timeout waiting for presentation request", func(t *testing.T) {
+ sampleConnID := uuid.New().String()
+
+ oobSvc := &mockoutofband.MockOobService{
+ AcceptInvitationHandle: func(*outofbandSvc.Invitation, outofbandSvc.Options) (string, error) {
+ return sampleConnID, nil
+ },
+ }
+ mockctx.ServiceMap[outofbandSvc.Name] = oobSvc
+
+ didexSvc := &mockdidexchange.MockDIDExchangeSvc{
+ RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
+ ch <- service.StateMsg{
+ Type: service.PostState,
+ StateID: didexchange.StateIDCompleted,
+ Properties: &mockdidexchange.MockEventProperties{ConnID: sampleConnID},
+ }
+
+ return nil
+ },
+ }
+ mockctx.ServiceMap[didexchange.DIDExchange] = didexSvc
+
+ ppSvc := &mockpresentproof.MockPresentProofSvc{
+ HandleFunc: func(service.DIDCommMsg) (string, error) {
+ return uuid.New().String(), nil
+ },
+ }
+ mockctx.ServiceMap[presentproofSvc.Name] = ppSvc
+
+ store, err := mockctx.StorageProvider().OpenStore(connection.Namespace)
+ require.NoError(t, err)
+
+ record := &connection.Record{
+ ConnectionID: sampleConnID,
+ MyDID: myDID,
+ TheirDID: theirDID,
+ }
+ recordBytes, err := json.Marshal(record)
+ require.NoError(t, err)
+ require.NoError(t, store.Put(fmt.Sprintf("conn_%s", sampleConnID), recordBytes))
+
+ wallet, err := New(sampleDIDCommUser, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, wallet)
+
+ didcomm, err := NewDidComm(wallet, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, didcomm)
+
+ token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+ require.NotEmpty(t, token)
+
+ defer wallet.Close()
+
+ msg, err := didcomm.ProposePresentation(token, &GenericInvitation{}, WithInitiateTimeout(600*time.Millisecond))
+ require.Error(t, err)
+ require.Contains(t, err.Error(), "timeout waiting for request presentation message")
+ require.Empty(t, msg)
+ })
+
+ t.Run("test propose presentation failure - action error", func(t *testing.T) {
+ sampleConnID := uuid.New().String()
+
+ oobSvc := &mockoutofband.MockOobService{
+ AcceptInvitationHandle: func(*outofbandSvc.Invitation, outofbandSvc.Options) (string, error) {
+ return sampleConnID, nil
+ },
+ }
+ mockctx.ServiceMap[outofbandSvc.Name] = oobSvc
+
+ didexSvc := &mockdidexchange.MockDIDExchangeSvc{
+ RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
+ ch <- service.StateMsg{
+ Type: service.PostState,
+ StateID: didexchange.StateIDCompleted,
+ Properties: &mockdidexchange.MockEventProperties{ConnID: sampleConnID},
+ }
+
+ return nil
+ },
+ }
+ mockctx.ServiceMap[didexchange.DIDExchange] = didexSvc
+
+ ppSvc := &mockpresentproof.MockPresentProofSvc{
+ HandleFunc: func(service.DIDCommMsg) (string, error) {
+ return uuid.New().String(), nil
+ },
+ ActionsFunc: func() ([]presentproofSvc.Action, error) {
+ return nil, fmt.Errorf(sampleWalletErr)
+ },
+ }
+ mockctx.ServiceMap[presentproofSvc.Name] = ppSvc
+
+ store, err := mockctx.StorageProvider().OpenStore(connection.Namespace)
+ require.NoError(t, err)
+
+ record := &connection.Record{
+ ConnectionID: sampleConnID,
+ TheirDID: theirDID,
+ }
+ recordBytes, err := json.Marshal(record)
+ require.NoError(t, err)
+ require.NoError(t, store.Put(fmt.Sprintf("conn_%s", sampleConnID), recordBytes))
+
+ wallet, err := New(sampleDIDCommUser, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, wallet)
+
+ didcomm, err := NewDidComm(wallet, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, didcomm)
+
+ token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+ require.NotEmpty(t, token)
+
+ defer wallet.Close()
+
+ msg, err := didcomm.ProposePresentation(token, &GenericInvitation{}, WithInitiateTimeout(1*time.Millisecond),
+ WithFromDID("did:sample:from"))
+ require.Error(t, err)
+ require.Contains(t, err.Error(), "timeout waiting for request presentation message")
+ require.Empty(t, msg)
+ })
+
+ t.Run("test propose presentation failure - oob v2 accept error", func(t *testing.T) {
+ ctrl := gomock.NewController(t)
+ defer ctrl.Finish()
+
+ expectErr := fmt.Errorf("expected error")
+
+ oobv2Svc := mockoutofbandv2.NewMockOobService(ctrl)
+ oobv2Svc.EXPECT().AcceptInvitation(gomock.Any(), gomock.Any()).Return("", expectErr).AnyTimes()
+
+ mockctx.ServiceMap[oobv2.Name] = oobv2Svc
+
+ wallet, err := New(sampleDIDCommUser, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, wallet)
+
+ didcomm, err := NewDidComm(wallet, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, didcomm)
+
+ token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+ require.NotEmpty(t, token)
+
+ defer wallet.Close()
+
+ invitation := GenericInvitation{}
+ err = json.Unmarshal([]byte(`{
+ "id": "abc123",
+ "type": "https://didcomm.org/out-of-band/2.0/invitation"
+ }`), &invitation)
+ require.NoError(t, err)
+
+ _, err = didcomm.ProposePresentation(token, &invitation,
+ WithConnectOptions(WithConnectTimeout(1*time.Millisecond)))
+ require.Error(t, err)
+ require.ErrorIs(t, err, expectErr)
+ require.Contains(t, err.Error(), "failed to accept OOB v2 invitation")
+ })
+}
+
+func TestWallet_PresentProof(t *testing.T) {
+ sampleDIDCommUser := uuid.New().String()
+ mockctx := newDidCommMockProvider(t)
+ err := CreateProfile(sampleDIDCommUser, mockctx, WithPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+
+ t.Run("test present proof success", func(t *testing.T) {
+ wallet, err := New(sampleDIDCommUser, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, wallet)
+
+ didcomm, err := NewDidComm(wallet, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, didcomm)
+
+ token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+ require.NotEmpty(t, token)
+
+ defer wallet.Close()
+
+ response, err := didcomm.PresentProof(token, uuid.New().String(), FromPresentation(&verifiable.Presentation{}))
+ require.NoError(t, err)
+ require.NotEmpty(t, response)
+ require.Equal(t, model.AckStatusPENDING, response.Status)
+ })
+
+ t.Run("test present proof success - wait for done with redirect", func(t *testing.T) {
+ thID := uuid.New().String()
+ mockPresentProofSvc := &mockpresentproof.MockPresentProofSvc{
+ RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
+ ch <- service.StateMsg{
+ Type: service.PostState,
+ StateID: presentproofSvc.StateNameDone,
+ Properties: &mockdidexchange.MockEventProperties{
+ Properties: map[string]interface{}{
+ webRedirectStatusKey: model.AckStatusOK,
+ webRedirectURLKey: exampleWebRedirect,
+ },
+ },
+ Msg: &mockMsg{thID: thID},
+ }
+
+ return nil
+ },
+ }
+ mockctx.ServiceMap[presentproofSvc.Name] = mockPresentProofSvc
+
+ wallet, err := New(sampleDIDCommUser, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, wallet)
+
+ didcomm, err := NewDidComm(wallet, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, didcomm)
+
+ token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+ require.NotEmpty(t, token)
+
+ defer wallet.Close()
+
+ response, err := didcomm.PresentProof(token, thID, FromPresentation(&verifiable.Presentation{}),
+ WaitForDone(1*time.Millisecond))
+ require.NoError(t, err)
+ require.NotEmpty(t, response)
+ require.Equal(t, model.AckStatusOK, response.Status)
+ require.Equal(t, exampleWebRedirect, response.RedirectURL)
+ })
+
+ t.Run("test present proof success - wait for abandoned with redirect", func(t *testing.T) {
+ thID := uuid.New().String()
+ mockPresentProofSvc := &mockpresentproof.MockPresentProofSvc{
+ RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
+ ch <- service.StateMsg{
+ Type: service.PostState,
+ StateID: presentproofSvc.StateNameAbandoned,
+ Properties: &mockdidexchange.MockEventProperties{
+ Properties: map[string]interface{}{
+ webRedirectStatusKey: model.AckStatusFAIL,
+ webRedirectURLKey: exampleWebRedirect,
+ },
+ },
+ Msg: &mockMsg{thID: thID},
+ }
+
+ return nil
+ },
+ }
+ mockctx.ServiceMap[presentproofSvc.Name] = mockPresentProofSvc
+
+ wallet, err := New(sampleDIDCommUser, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, wallet)
+
+ didcomm, err := NewDidComm(wallet, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, didcomm)
+
+ token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+ require.NotEmpty(t, token)
+
+ defer wallet.Close()
+
+ response, err := didcomm.PresentProof(token, thID, FromPresentation(&verifiable.Presentation{}),
+ WaitForDone(1*time.Millisecond))
+ require.NoError(t, err)
+ require.NotEmpty(t, response)
+ require.Equal(t, model.AckStatusFAIL, response.Status)
+ require.Equal(t, exampleWebRedirect, response.RedirectURL)
+ })
+
+ t.Run("test present proof success - wait for done no redirect", func(t *testing.T) {
+ thID := uuid.New().String()
+ mockPresentProofSvc := &mockpresentproof.MockPresentProofSvc{
+ RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
+ ch <- service.StateMsg{
+ Type: service.PostState,
+ StateID: presentproofSvc.StateNameDone,
+ Properties: &mockdidexchange.MockEventProperties{},
+ Msg: &mockMsg{thID: thID},
+ }
+
+ return nil
+ },
+ }
+ mockctx.ServiceMap[presentproofSvc.Name] = mockPresentProofSvc
+
+ wallet, err := New(sampleDIDCommUser, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, wallet)
+
+ didcomm, err := NewDidComm(wallet, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, didcomm)
+
+ token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+ require.NotEmpty(t, token)
+
+ defer wallet.Close()
+
+ response, err := didcomm.PresentProof(token, thID, FromPresentation(&verifiable.Presentation{}),
+ WaitForDone(1*time.Millisecond))
+ require.NoError(t, err)
+ require.NotEmpty(t, response)
+ require.Equal(t, model.AckStatusOK, response.Status)
+ require.Empty(t, response.RedirectURL)
+ })
+
+ t.Run("test present proof failure - wait for abandoned no redirect", func(t *testing.T) {
+ thID := uuid.New().String()
+ mockPresentProofSvc := &mockpresentproof.MockPresentProofSvc{
+ RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
+ ch <- service.StateMsg{
+ Type: service.PostState,
+ StateID: presentproofSvc.StateNameAbandoned,
+ Properties: &mockdidexchange.MockEventProperties{},
+ Msg: &mockMsg{thID: thID},
+ }
+
+ return nil
+ },
+ }
+ mockctx.ServiceMap[presentproofSvc.Name] = mockPresentProofSvc
+
+ wallet, err := New(sampleDIDCommUser, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, wallet)
+
+ didcomm, err := NewDidComm(wallet, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, didcomm)
+
+ token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+ require.NotEmpty(t, token)
+
+ defer wallet.Close()
+
+ response, err := didcomm.PresentProof(token, thID, FromPresentation(&verifiable.Presentation{}),
+ WaitForDone(1*time.Millisecond))
+ require.NoError(t, err)
+ require.NotEmpty(t, response)
+ require.Equal(t, model.AckStatusFAIL, response.Status)
+ require.Empty(t, response.RedirectURL)
+ })
+
+ t.Run("test present proof failure", func(t *testing.T) {
+ ppSvc := &mockpresentproof.MockPresentProofSvc{
+ ActionContinueFunc: func(string, ...presentproofSvc.Opt) error {
+ return fmt.Errorf(sampleWalletErr)
+ },
+ }
+
+ mockctx.ServiceMap[presentproofSvc.Name] = ppSvc
+
+ wallet, err := New(sampleDIDCommUser, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, wallet)
+
+ didcomm, err := NewDidComm(wallet, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, didcomm)
+
+ token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+ require.NotEmpty(t, token)
+
+ defer wallet.Close()
+
+ response, err := didcomm.PresentProof(token, uuid.New().String(), FromRawPresentation([]byte("{}")))
+ require.Error(t, err)
+ require.Contains(t, err.Error(), sampleWalletErr)
+ require.Empty(t, response)
+ })
+
+ t.Run("test present proof failure - failed to register message event", func(t *testing.T) {
+ thID := uuid.New().String()
+ mockPresentProofSvc := &mockpresentproof.MockPresentProofSvc{
+ RegisterMsgEventErr: errors.New(sampleWalletErr),
+ }
+ mockctx.ServiceMap[presentproofSvc.Name] = mockPresentProofSvc
+
+ wallet, err := New(sampleDIDCommUser, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, wallet)
+
+ didcomm, err := NewDidComm(wallet, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, didcomm)
+
+ token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+ require.NotEmpty(t, token)
+
+ defer wallet.Close()
+
+ response, err := didcomm.PresentProof(token, thID, FromPresentation(&verifiable.Presentation{}),
+ WaitForDone(1*time.Millisecond))
+ require.Error(t, err)
+ require.Contains(t, err.Error(), sampleWalletErr)
+ require.Empty(t, response)
+ })
+
+ t.Run("test present proof failure - wait for done timeout", func(t *testing.T) {
+ thID := uuid.New().String()
+ mockPresentProofSvc := &mockpresentproof.MockPresentProofSvc{
+ RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
+ ch <- service.StateMsg{
+ Type: service.PreState,
+ }
+
+ ch <- service.StateMsg{
+ Type: service.PostState,
+ }
+
+ ch <- service.StateMsg{
+ Type: service.PostState,
+ Msg: &mockMsg{thID: "invalid"},
+ }
+
+ ch <- service.StateMsg{
+ Type: service.PostState,
+ StateID: "invalid",
+ Msg: &mockMsg{thID: thID, fail: errors.New(sampleWalletErr)},
+ }
+
+ ch <- service.StateMsg{
+ Type: service.PostState,
+ StateID: "invalid",
+ Msg: &mockMsg{thID: thID},
+ }
+
+ return nil
+ },
+ UnregisterMsgEventErr: errors.New(sampleWalletErr),
+ }
+ mockctx.ServiceMap[presentproofSvc.Name] = mockPresentProofSvc
+
+ wallet, err := New(sampleDIDCommUser, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, wallet)
+
+ didcomm, err := NewDidComm(wallet, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, didcomm)
+
+ token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+ require.NotEmpty(t, token)
+
+ defer wallet.Close()
+
+ response, err := didcomm.PresentProof(token, thID, FromPresentation(&verifiable.Presentation{}),
+ WaitForDone(1*time.Millisecond))
+ require.Error(t, err)
+ require.Contains(t, err.Error(), "time out waiting for credential interaction to get completed")
+ require.Empty(t, response)
+ })
+}
+
+func TestWallet_ProposeCredential(t *testing.T) {
+ sampleDIDCommUser := uuid.New().String()
+ mockctx := newDidCommMockProvider(t)
+ err := CreateProfile(sampleDIDCommUser, mockctx, WithPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+
+ const (
+ myDID = "did:mydid:123"
+ theirDID = "did:theirdid:123"
+ )
+
+ t.Run("test propose credential success", func(t *testing.T) {
+ sampleConnID := uuid.New().String()
+
+ oobSvc := &mockoutofband.MockOobService{
+ AcceptInvitationHandle: func(*outofbandSvc.Invitation, outofbandSvc.Options) (string, error) {
+ return sampleConnID, nil
+ },
+ }
+ mockctx.ServiceMap[outofbandSvc.Name] = oobSvc
+
+ didexSvc := &mockdidexchange.MockDIDExchangeSvc{
+ RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
+ ch <- service.StateMsg{
+ Type: service.PostState,
+ StateID: didexchange.StateIDCompleted,
+ Properties: &mockdidexchange.MockEventProperties{ConnID: sampleConnID},
+ }
+
+ return nil
+ },
+ }
+ mockctx.ServiceMap[didexchange.DIDExchange] = didexSvc
+
+ thID := uuid.New().String()
+
+ icSvc := &mockissuecredential.MockIssueCredentialSvc{
+ ActionsFunc: func() ([]issuecredentialsvc.Action, error) {
+ return []issuecredentialsvc.Action{
+ {
+ PIID: thID,
+ Msg: service.NewDIDCommMsgMap(&issuecredentialsvc.OfferCredentialV2{
+ Comment: sampleMsgComment,
+ }),
+ MyDID: myDID,
+ TheirDID: theirDID,
+ },
+ }, nil
+ },
+ HandleFunc: func(service.DIDCommMsg) (string, error) {
+ return thID, nil
+ },
+ }
+
+ mockctx.ServiceMap[outofbandSvc.Name] = oobSvc
+ mockctx.ServiceMap[issuecredentialsvc.Name] = icSvc
+
+ store, err := mockctx.StorageProvider().OpenStore(connection.Namespace)
+ require.NoError(t, err)
+
+ record := &connection.Record{
+ ConnectionID: sampleConnID,
+ MyDID: myDID,
+ TheirDID: theirDID,
+ }
+ recordBytes, err := json.Marshal(record)
+ require.NoError(t, err)
+ require.NoError(t, store.Put(fmt.Sprintf("conn_%s", sampleConnID), recordBytes))
+
+ wallet, err := New(sampleDIDCommUser, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, wallet)
+
+ didcomm, err := NewDidComm(wallet, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, didcomm)
+
+ token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+ require.NotEmpty(t, token)
+
+ defer wallet.Close()
+
+ msg, err := didcomm.ProposeCredential(token, &GenericInvitation{},
+ WithConnectOptions(WithConnectTimeout(1*time.Millisecond)))
+ require.NoError(t, err)
+ require.NotEmpty(t, msg)
+
+ offer := &issuecredentialsvc.OfferCredentialV2{}
+
+ err = msg.Decode(offer)
+ require.NoError(t, err)
+ require.NotEmpty(t, offer)
+ require.Equal(t, sampleMsgComment, offer.Comment)
+ })
+
+ t.Run("test propose credential failure - did connect failure", func(t *testing.T) {
+ didexSvc := &mockdidexchange.MockDIDExchangeSvc{
+ RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
+ return fmt.Errorf(sampleWalletErr)
+ },
+ }
+ mockctx.ServiceMap[didexchange.DIDExchange] = didexSvc
+
+ wallet, err := New(sampleDIDCommUser, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, wallet)
+
+ didcomm, err := NewDidComm(wallet, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, didcomm)
+
+ token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+ require.NotEmpty(t, token)
+
+ defer wallet.Close()
+
+ msg, err := didcomm.ProposeCredential(token, &GenericInvitation{})
+ require.Error(t, err)
+ require.Contains(t, err.Error(), sampleWalletErr)
+ require.Contains(t, err.Error(), "failed to perform did connection")
+ require.Empty(t, msg)
+ })
+
+ t.Run("test propose credential failure - oobv2 accept error", func(t *testing.T) {
+ ctrl := gomock.NewController(t)
+ defer ctrl.Finish()
+
+ expectErr := fmt.Errorf("expected error")
+
+ oobv2Svc := mockoutofbandv2.NewMockOobService(ctrl)
+ oobv2Svc.EXPECT().AcceptInvitation(gomock.Any(), gomock.Any()).Return("", expectErr).AnyTimes()
+
+ mockctx.ServiceMap[oobv2.Name] = oobv2Svc
+
+ wallet, err := New(sampleDIDCommUser, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, wallet)
+
+ didcomm, err := NewDidComm(wallet, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, didcomm)
+
+ token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+ require.NotEmpty(t, token)
+
+ defer wallet.Close()
+
+ invitation := GenericInvitation{}
+ err = json.Unmarshal([]byte(`{
+ "id": "abc123",
+ "type": "https://didcomm.org/out-of-band/2.0/invitation"
+ }`), &invitation)
+ require.NoError(t, err)
+
+ _, err = didcomm.ProposeCredential(token, &invitation,
+ WithConnectOptions(WithConnectTimeout(1*time.Millisecond)))
+ require.Error(t, err)
+ require.ErrorIs(t, err, expectErr)
+ require.Contains(t, err.Error(), "failed to accept OOB v2 invitation")
+ })
+
+ t.Run("test propose credential failure - no connection found", func(t *testing.T) {
+ sampleConnID := uuid.New().String()
+
+ oobSvc := &mockoutofband.MockOobService{
+ AcceptInvitationHandle: func(*outofbandSvc.Invitation, outofbandSvc.Options) (string, error) {
+ return sampleConnID, nil
+ },
+ }
+ mockctx.ServiceMap[outofbandSvc.Name] = oobSvc
+
+ didexSvc := &mockdidexchange.MockDIDExchangeSvc{
+ RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
+ ch <- service.StateMsg{
+ Type: service.PostState,
+ StateID: didexchange.StateIDCompleted,
+ Properties: &mockdidexchange.MockEventProperties{ConnID: sampleConnID},
+ }
+
+ return nil
+ },
+ }
+ mockctx.ServiceMap[didexchange.DIDExchange] = didexSvc
+
+ wallet, err := New(sampleDIDCommUser, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, wallet)
+
+ didcomm, err := NewDidComm(wallet, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, didcomm)
+
+ token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+ require.NotEmpty(t, token)
+
+ defer wallet.Close()
+
+ msg, err := didcomm.ProposeCredential(token, &GenericInvitation{})
+ require.Error(t, err)
+ require.Contains(t, err.Error(), "failed to lookup connection")
+ require.Empty(t, msg)
+ })
+
+ t.Run("test propose credential failure - failed to send", func(t *testing.T) {
+ sampleConnID := uuid.New().String()
+
+ oobSvc := &mockoutofband.MockOobService{
+ AcceptInvitationHandle: func(*outofbandSvc.Invitation, outofbandSvc.Options) (string, error) {
+ return sampleConnID, nil
+ },
+ }
+ mockctx.ServiceMap[outofbandSvc.Name] = oobSvc
+
+ didexSvc := &mockdidexchange.MockDIDExchangeSvc{
+ RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
+ ch <- service.StateMsg{
+ Type: service.PostState,
+ StateID: didexchange.StateIDCompleted,
+ Properties: &mockdidexchange.MockEventProperties{ConnID: sampleConnID},
+ }
+
+ return nil
+ },
+ }
+ mockctx.ServiceMap[didexchange.DIDExchange] = didexSvc
+
+ icSvc := &mockissuecredential.MockIssueCredentialSvc{
+ HandleFunc: func(service.DIDCommMsg) (string, error) {
+ return "", fmt.Errorf(sampleWalletErr)
+ },
+ HandleOutboundFunc: func(service.DIDCommMsg, string, string) (string, error) {
+ return "", fmt.Errorf(sampleWalletErr)
+ },
+ }
+ mockctx.ServiceMap[issuecredentialsvc.Name] = icSvc
+
+ store, err := mockctx.StorageProvider().OpenStore(connection.Namespace)
+ require.NoError(t, err)
+
+ record := &connection.Record{
+ ConnectionID: sampleConnID,
+ MyDID: myDID,
+ TheirDID: theirDID,
+ }
+ recordBytes, err := json.Marshal(record)
+ require.NoError(t, err)
+ require.NoError(t, store.Put(fmt.Sprintf("conn_%s", sampleConnID), recordBytes))
+
+ wallet, err := New(sampleDIDCommUser, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, wallet)
+
+ didcomm, err := NewDidComm(wallet, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, didcomm)
+
+ token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+ require.NotEmpty(t, token)
+
+ defer wallet.Close()
+
+ msg, err := didcomm.ProposeCredential(token, &GenericInvitation{})
+ require.Error(t, err)
+ require.Contains(t, err.Error(), sampleWalletErr)
+ require.Contains(t, err.Error(), "failed to propose credential from wallet")
+ require.Empty(t, msg)
+ })
+
+ t.Run("test propose credential failure - timeout waiting for offer credential msg", func(t *testing.T) {
+ sampleConnID := uuid.New().String()
+
+ oobSvc := &mockoutofband.MockOobService{
+ AcceptInvitationHandle: func(*outofbandSvc.Invitation, outofbandSvc.Options) (string, error) {
+ return sampleConnID, nil
+ },
+ }
+ mockctx.ServiceMap[outofbandSvc.Name] = oobSvc
+
+ didexSvc := &mockdidexchange.MockDIDExchangeSvc{
+ RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
+ ch <- service.StateMsg{
+ Type: service.PostState,
+ StateID: didexchange.StateIDCompleted,
+ Properties: &mockdidexchange.MockEventProperties{ConnID: sampleConnID},
+ }
+
+ return nil
+ },
+ }
+ mockctx.ServiceMap[didexchange.DIDExchange] = didexSvc
+
+ icSvc := &mockissuecredential.MockIssueCredentialSvc{
+ HandleFunc: func(service.DIDCommMsg) (string, error) {
+ return uuid.New().String(), nil
+ },
+ }
+ mockctx.ServiceMap[issuecredentialsvc.Name] = icSvc
+
+ store, err := mockctx.StorageProvider().OpenStore(connection.Namespace)
+ require.NoError(t, err)
+
+ record := &connection.Record{
+ ConnectionID: sampleConnID,
+ MyDID: myDID,
+ TheirDID: theirDID,
+ }
+ recordBytes, err := json.Marshal(record)
+ require.NoError(t, err)
+ require.NoError(t, store.Put(fmt.Sprintf("conn_%s", sampleConnID), recordBytes))
+
+ wallet, err := New(sampleDIDCommUser, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, wallet)
+
+ didcomm, err := NewDidComm(wallet, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, didcomm)
+
+ token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+ require.NotEmpty(t, token)
+
+ defer wallet.Close()
+
+ msg, err := didcomm.ProposeCredential(token, &GenericInvitation{}, WithInitiateTimeout(600*time.Millisecond))
+ require.Error(t, err)
+ require.Contains(t, err.Error(), "timeout waiting for offer credential message")
+ require.Empty(t, msg)
+ })
+
+ t.Run("test propose presentation failure - action error", func(t *testing.T) {
+ sampleConnID := uuid.New().String()
+
+ oobSvc := &mockoutofband.MockOobService{
+ AcceptInvitationHandle: func(*outofbandSvc.Invitation, outofbandSvc.Options) (string, error) {
+ return sampleConnID, nil
+ },
+ }
+ mockctx.ServiceMap[outofbandSvc.Name] = oobSvc
+
+ didexSvc := &mockdidexchange.MockDIDExchangeSvc{
+ RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
+ ch <- service.StateMsg{
+ Type: service.PostState,
+ StateID: didexchange.StateIDCompleted,
+ Properties: &mockdidexchange.MockEventProperties{ConnID: sampleConnID},
+ }
+
+ return nil
+ },
+ }
+ mockctx.ServiceMap[didexchange.DIDExchange] = didexSvc
+
+ icSvc := &mockissuecredential.MockIssueCredentialSvc{
+ HandleFunc: func(service.DIDCommMsg) (string, error) {
+ return uuid.New().String(), nil
+ },
+ ActionsFunc: func() ([]issuecredentialsvc.Action, error) {
+ return nil, fmt.Errorf(sampleWalletErr)
+ },
+ }
+ mockctx.ServiceMap[issuecredentialsvc.Name] = icSvc
+
+ store, err := mockctx.StorageProvider().OpenStore(connection.Namespace)
+ require.NoError(t, err)
+
+ record := &connection.Record{
+ ConnectionID: sampleConnID,
+ TheirDID: theirDID,
+ }
+ recordBytes, err := json.Marshal(record)
+ require.NoError(t, err)
+ require.NoError(t, store.Put(fmt.Sprintf("conn_%s", sampleConnID), recordBytes))
+
+ wallet, err := New(sampleDIDCommUser, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, wallet)
+
+ didcomm, err := NewDidComm(wallet, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, didcomm)
+
+ token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+ require.NotEmpty(t, token)
+
+ defer wallet.Close()
+
+ msg, err := didcomm.ProposeCredential(token, &GenericInvitation{}, WithInitiateTimeout(1*time.Millisecond),
+ WithFromDID("did:sample:from"))
+ require.Error(t, err)
+ require.Contains(t, err.Error(), "timeout waiting for offer credential message")
+ require.Empty(t, msg)
+ })
+}
+
+func TestWallet_RequestCredential(t *testing.T) {
+ sampleDIDCommUser := uuid.New().String()
+ mockctx := newDidCommMockProvider(t)
+ err := CreateProfile(sampleDIDCommUser, mockctx, WithPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+
+ t.Run("test request credential success", func(t *testing.T) {
+ wallet, err := New(sampleDIDCommUser, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, wallet)
+
+ didcomm, err := NewDidComm(wallet, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, didcomm)
+
+ token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+ require.NotEmpty(t, token)
+
+ defer wallet.Close()
+
+ response, err := didcomm.RequestCredential(token, uuid.New().String(), FromPresentation(&verifiable.Presentation{}))
+ require.NoError(t, err)
+ require.NotEmpty(t, response)
+ require.Equal(t, model.AckStatusPENDING, response.Status)
+ })
+
+ t.Run("test request credential success - wait for done with redirect", func(t *testing.T) {
+ thID := uuid.New().String()
+
+ icSvc := &mockissuecredential.MockIssueCredentialSvc{
+ RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
+ ch <- service.StateMsg{
+ Type: service.PostState,
+ StateID: stateNameDone,
+ Properties: &mockdidexchange.MockEventProperties{
+ Properties: map[string]interface{}{
+ webRedirectStatusKey: model.AckStatusOK,
+ webRedirectURLKey: exampleWebRedirect,
+ },
+ },
+ Msg: &mockMsg{thID: thID},
+ }
+
+ return nil
+ },
+ }
+ mockctx.ServiceMap[issuecredentialsvc.Name] = icSvc
+
+ wallet, err := New(sampleDIDCommUser, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, wallet)
+
+ didcomm, err := NewDidComm(wallet, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, didcomm)
+
+ token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+ require.NotEmpty(t, token)
+
+ defer wallet.Close()
+
+ response, err := didcomm.RequestCredential(token, thID, FromPresentation(&verifiable.Presentation{}),
+ WaitForDone(0))
+ require.NoError(t, err)
+ require.NotEmpty(t, response)
+ require.Equal(t, model.AckStatusOK, response.Status)
+ require.Equal(t, exampleWebRedirect, response.RedirectURL)
+ })
+
+ t.Run("test for request credential - wait for problem report with redirect", func(t *testing.T) {
+ thID := uuid.New().String()
+
+ icSvc := &mockissuecredential.MockIssueCredentialSvc{
+ RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
+ ch <- service.StateMsg{
+ Type: service.PostState,
+ StateID: stateNameAbandoned,
+ Properties: &mockdidexchange.MockEventProperties{
+ Properties: map[string]interface{}{
+ webRedirectStatusKey: model.AckStatusFAIL,
+ webRedirectURLKey: exampleWebRedirect,
+ },
+ },
+ Msg: &mockMsg{thID: thID},
+ }
+
+ return nil
+ },
+ }
+ mockctx.ServiceMap[issuecredentialsvc.Name] = icSvc
+
+ wallet, err := New(sampleDIDCommUser, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, wallet)
+
+ didcomm, err := NewDidComm(wallet, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, didcomm)
+
+ token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+ require.NotEmpty(t, token)
+
+ defer wallet.Close()
+
+ response, err := didcomm.RequestCredential(token, thID, FromPresentation(&verifiable.Presentation{}),
+ WaitForDone(1*time.Millisecond))
+ require.NoError(t, err)
+ require.NotEmpty(t, response)
+ require.Equal(t, model.AckStatusFAIL, response.Status)
+ require.Equal(t, exampleWebRedirect, response.RedirectURL)
+ })
+
+ t.Run("test request credential success - wait for done no redirect", func(t *testing.T) {
+ thID := uuid.New().String()
+
+ icSvc := &mockissuecredential.MockIssueCredentialSvc{
+ RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
+ ch <- service.StateMsg{
+ Type: service.PostState,
+ StateID: stateNameDone,
+ Properties: &mockdidexchange.MockEventProperties{},
+ Msg: &mockMsg{thID: thID},
+ }
+
+ return nil
+ },
+ }
+ mockctx.ServiceMap[issuecredentialsvc.Name] = icSvc
+
+ wallet, err := New(sampleDIDCommUser, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, wallet)
+
+ didcomm, err := NewDidComm(wallet, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, didcomm)
+
+ token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+ require.NotEmpty(t, token)
+
+ defer wallet.Close()
+
+ response, err := didcomm.RequestCredential(token, thID, FromPresentation(&verifiable.Presentation{}),
+ WaitForDone(10*time.Millisecond))
+ require.NoError(t, err)
+ require.NotEmpty(t, response)
+ require.Equal(t, model.AckStatusOK, response.Status)
+ require.Empty(t, response.RedirectURL)
+ })
+
+ t.Run("test request credential failure - wait for problem report no redirect", func(t *testing.T) {
+ thID := uuid.New().String()
+
+ icSvc := &mockissuecredential.MockIssueCredentialSvc{
+ RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
+ ch <- service.StateMsg{
+ Type: service.PostState,
+ StateID: stateNameAbandoned,
+ Properties: &mockdidexchange.MockEventProperties{},
+ Msg: &mockMsg{thID: thID},
+ }
+
+ return nil
+ },
+ }
+ mockctx.ServiceMap[issuecredentialsvc.Name] = icSvc
+
+ wallet, err := New(sampleDIDCommUser, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, wallet)
+
+ didcomm, err := NewDidComm(wallet, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, didcomm)
+
+ token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+ require.NotEmpty(t, token)
+
+ defer wallet.Close()
+
+ response, err := didcomm.RequestCredential(token, thID, FromPresentation(&verifiable.Presentation{}),
+ WaitForDone(1*time.Millisecond))
+ require.NoError(t, err)
+ require.NotEmpty(t, response)
+ require.Equal(t, model.AckStatusFAIL, response.Status)
+ require.Empty(t, response.RedirectURL)
+ })
+
+ t.Run("test request credential failure", func(t *testing.T) {
+ icSvc := &mockissuecredential.MockIssueCredentialSvc{
+ ActionContinueFunc: func(string, ...issuecredentialsvc.Opt) error {
+ return fmt.Errorf(sampleWalletErr)
+ },
+ }
+ mockctx.ServiceMap[issuecredentialsvc.Name] = icSvc
+
+ wallet, err := New(sampleDIDCommUser, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, wallet)
+
+ didcomm, err := NewDidComm(wallet, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, didcomm)
+
+ token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+ require.NotEmpty(t, token)
+
+ defer wallet.Close()
+
+ response, err := didcomm.RequestCredential(token, uuid.New().String(), FromRawPresentation([]byte("{}")))
+ require.Error(t, err)
+ require.Contains(t, err.Error(), sampleWalletErr)
+ require.Empty(t, response)
+ })
+
+ t.Run("test request credential failure - failed to register msg event", func(t *testing.T) {
+ thID := uuid.New().String()
+ icSvc := &mockissuecredential.MockIssueCredentialSvc{
+ RegisterMsgEventErr: errors.New(sampleWalletErr),
+ }
+ mockctx.ServiceMap[issuecredentialsvc.Name] = icSvc
+
+ wallet, err := New(sampleDIDCommUser, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, wallet)
+
+ didcomm, err := NewDidComm(wallet, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, didcomm)
+
+ token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+ require.NotEmpty(t, token)
+
+ defer wallet.Close()
+
+ response, err := didcomm.RequestCredential(token, thID, FromPresentation(&verifiable.Presentation{}),
+ WaitForDone(1*time.Millisecond))
+ require.Error(t, err)
+ require.Contains(t, err.Error(), sampleWalletErr)
+ require.Empty(t, response)
+ })
+
+ t.Run("test request credential success - wait for done timeout", func(t *testing.T) {
+ thID := uuid.New().String()
+
+ icSvc := &mockissuecredential.MockIssueCredentialSvc{
+ RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
+ ch <- service.StateMsg{
+ Type: service.PreState,
+ }
+
+ ch <- service.StateMsg{
+ Type: service.PostState,
+ }
+
+ ch <- service.StateMsg{
+ Type: service.PostState,
+ Msg: &mockMsg{thID: "invalid"},
+ }
+
+ ch <- service.StateMsg{
+ Type: service.PostState,
+ StateID: "invalid",
+ Msg: &mockMsg{thID: thID, fail: errors.New(sampleWalletErr)},
+ }
+
+ ch <- service.StateMsg{
+ Type: service.PostState,
+ StateID: "invalid",
+ Msg: &mockMsg{thID: thID},
+ }
+
+ return nil
+ },
+ UnregisterMsgEventErr: errors.New(sampleWalletErr),
+ }
+ mockctx.ServiceMap[issuecredentialsvc.Name] = icSvc
+
+ wallet, err := New(sampleDIDCommUser, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, wallet)
+
+ didcomm, err := NewDidComm(wallet, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, didcomm)
+
+ token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
+ require.NoError(t, err)
+ require.NotEmpty(t, token)
+
+ defer wallet.Close()
+
+ response, err := didcomm.RequestCredential(token, thID, FromPresentation(&verifiable.Presentation{}),
+ WaitForDone(700*time.Millisecond))
+ require.Error(t, err)
+ require.Contains(t, err.Error(), "time out waiting for credential interaction to get completed")
+ require.Empty(t, response)
+ })
+}
+
+func newDidCommMockProvider(t *testing.T) *mockprovider.Provider {
+ t.Helper()
+
+ loader, err := ldtestutil.DocumentLoader()
+ require.NoError(t, err)
+
+ serviceMap := map[string]interface{}{
+ presentproofSvc.Name: &mockpresentproof.MockPresentProofSvc{},
+ outofbandSvc.Name: &mockoutofband.MockOobService{},
+ didexchange.DIDExchange: &mockdidexchange.MockDIDExchangeSvc{},
+ mediator.Coordination: &mockmediator.MockMediatorSvc{},
+ issuecredentialsvc.Name: &mockissuecredential.MockIssueCredentialSvc{},
+ oobv2.Name: &mockoutofbandv2.MockOobService{},
+ }
+
+ return &mockprovider.Provider{
+ StorageProviderValue: mockstorage.NewMockStoreProvider(),
+ ProtocolStateStorageProviderValue: mockstorage.NewMockStoreProvider(),
+ DocumentLoaderValue: loader,
+ ServiceMap: serviceMap,
+ }
+}
+
+// mockMsg containing custom parent thread ID.
+type mockMsg struct {
+ *service.DIDCommMsgMap
+ thID string
+ fail error
+ msgType string
+}
+
+func (m *mockMsg) ParentThreadID() string {
+ return m.thID
+}
+
+func (m *mockMsg) ThreadID() (string, error) {
+ return m.thID, m.fail
+}
+
+func (m *mockMsg) Type() string {
+ if m.msgType != "" {
+ return m.msgType
+ }
+
+ if m.DIDCommMsgMap != nil {
+ return m.DIDCommMsgMap.Type()
+ }
+
+ return ""
+}
diff --git a/pkg/wallet/wallet.go b/pkg/wallet/wallet.go
index a50ec5dc4..2b5b8ddd3 100644
--- a/pkg/wallet/wallet.go
+++ b/pkg/wallet/wallet.go
@@ -7,29 +7,15 @@ SPDX-License-Identifier: Apache-2.0
package wallet
import (
- "context"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
- "time"
- "github.com/google/uuid"
"github.com/piprate/json-gold/ld"
- "github.com/hyperledger/aries-framework-go/pkg/client/didexchange"
- "github.com/hyperledger/aries-framework-go/pkg/client/issuecredential"
- "github.com/hyperledger/aries-framework-go/pkg/client/outofband"
- "github.com/hyperledger/aries-framework-go/pkg/client/outofbandv2"
- "github.com/hyperledger/aries-framework-go/pkg/client/presentproof"
"github.com/hyperledger/aries-framework-go/pkg/common/log"
"github.com/hyperledger/aries-framework-go/pkg/crypto"
- "github.com/hyperledger/aries-framework-go/pkg/didcomm/common/model"
- "github.com/hyperledger/aries-framework-go/pkg/didcomm/common/service"
- "github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/decorator"
- didexchangeSvc "github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/didexchange"
- issuecredentialsvc "github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/issuecredential"
- outofbandv2svc "github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/outofbandv2"
"github.com/hyperledger/aries-framework-go/pkg/doc/cm"
"github.com/hyperledger/aries-framework-go/pkg/doc/did"
"github.com/hyperledger/aries-framework-go/pkg/doc/signature/jsonld"
@@ -41,7 +27,6 @@ import (
"github.com/hyperledger/aries-framework-go/pkg/doc/verifiable"
"github.com/hyperledger/aries-framework-go/pkg/framework/aries/api/vdr"
"github.com/hyperledger/aries-framework-go/pkg/kms"
- "github.com/hyperledger/aries-framework-go/pkg/store/connection"
"github.com/hyperledger/aries-framework-go/spi/storage"
)
@@ -57,25 +42,12 @@ const (
// miscellaneous constants.
const (
- bbsContext = "https://w3id.org/security/bbs/v1"
- emptyRawLength = 4
- msgEventBufferSize = 10
- ldJSONMimeType = "application/ld+json"
-
- // protocol states.
- stateNameAbandoned = "abandoned"
- stateNameAbandoning = "abandoning"
- stateNameDone = "done"
+ bbsContext = "https://w3id.org/security/bbs/v1"
+ emptyRawLength = 4
// web redirect constants.
webRedirectStatusKey = "status"
webRedirectURLKey = "url"
-
- // timeout constants.
- defaultDIDExchangeTimeOut = 120 * time.Second
- defaultWaitForRequestPresentationTimeOut = 120 * time.Second
- defaultWaitForPresentProofDone = 120 * time.Second
- retryDelay = 500 * time.Millisecond
)
// proof options.
@@ -98,19 +70,6 @@ type provider interface {
Crypto() crypto.Crypto
JSONLDDocumentLoader() ld.DocumentLoader
MediaTypeProfiles() []string
- didCommProvider // to be used only if wallet needs to be participated in DIDComm.
-}
-
-// didCommProvider to be used only if wallet needs to be participated in DIDComm operation.
-// TODO: using wallet KMS instead of provider KMS.
-// TODO: reconcile Protocol storage with wallet store.
-type didCommProvider interface {
- KMS() kms.KeyManager
- ServiceEndpoint() string
- ProtocolStateStorageProvider() storage.Provider
- Service(id string) (interface{}, error)
- KeyType() kms.KeyType
- KeyAgreementType() kms.KeyType
}
type provable interface {
@@ -139,24 +98,6 @@ type Wallet struct {
// document loader for JSON-LD contexts
jsonldDocumentLoader ld.DocumentLoader
-
- // present proof client
- presentProofClient *presentproof.Client
-
- // issue credential client
- issueCredentialClient *issuecredential.Client
-
- // out of band client
- oobClient *outofband.Client
-
- // out of band v2 client
- oobV2Client *outofbandv2.Client
-
- // did-exchange client
- didexchangeClient *didexchange.Client
-
- // connection lookup
- connectionLookup *connection.Lookup
}
// New returns new verifiable credential wallet for given user.
@@ -174,50 +115,14 @@ func New(userID string, ctx provider) (*Wallet, error) {
return nil, fmt.Errorf("failed to get VC wallet profile: %w", err)
}
- presentProofClient, err := presentproof.New(ctx)
- if err != nil {
- return nil, fmt.Errorf("failed to initialize present proof client: %w", err)
- }
-
- issueCredentialClient, err := issuecredential.New(ctx)
- if err != nil {
- return nil, fmt.Errorf("failed to initialize issue credential client: %w", err)
- }
-
- oobClient, err := outofband.New(ctx)
- if err != nil {
- return nil, fmt.Errorf("failed to initialize out-of-band client: %w", err)
- }
-
- oobV2Client, err := outofbandv2.New(ctx)
- if err != nil {
- return nil, fmt.Errorf("failed to initialize out-of-band v2 client: %w", err)
- }
-
- connectionLookup, err := connection.NewLookup(ctx)
- if err != nil {
- return nil, fmt.Errorf("failed to initialize connection lookup: %w", err)
- }
-
- didexchangeClient, err := didexchange.New(ctx)
- if err != nil {
- return nil, fmt.Errorf("failed to initialize didexchange client: %w", err)
- }
-
return &Wallet{
- userID: userID,
- profile: profile,
- storeProvider: ctx.StorageProvider(),
- walletCrypto: ctx.Crypto(),
- contents: newContentStore(ctx.StorageProvider(), ctx.JSONLDDocumentLoader(), profile),
- vdr: ctx.VDRegistry(),
- jsonldDocumentLoader: ctx.JSONLDDocumentLoader(),
- presentProofClient: presentProofClient,
- issueCredentialClient: issueCredentialClient,
- oobClient: oobClient,
- oobV2Client: oobV2Client,
- didexchangeClient: didexchangeClient,
- connectionLookup: connectionLookup,
+ userID: userID,
+ profile: profile,
+ storeProvider: ctx.StorageProvider(),
+ walletCrypto: ctx.Crypto(),
+ contents: newContentStore(ctx.StorageProvider(), ctx.JSONLDDocumentLoader(), profile),
+ vdr: ctx.VDRegistry(),
+ jsonldDocumentLoader: ctx.JSONLDDocumentLoader(),
}, nil
}
@@ -646,337 +551,6 @@ func (c *Wallet) CreateKeyPair(authToken string, keyType kms.KeyType) (*KeyPair,
}, nil
}
-// Connect accepts out-of-band invitations and performs DID exchange.
-//
-// Args:
-// - authToken: authorization for performing create key pair operation.
-// - invitation: out-of-band invitation.
-// - options: connection options.
-//
-// Returns:
-// - connection ID if DID exchange is successful.
-// - error if operation false.
-//
-func (c *Wallet) Connect(authToken string, invitation *outofband.Invitation, options ...ConnectOptions) (string, error) { //nolint: lll
- statusCh := make(chan service.StateMsg, msgEventBufferSize)
-
- err := c.didexchangeClient.RegisterMsgEvent(statusCh)
- if err != nil {
- return "", fmt.Errorf("failed to register msg event : %w", err)
- }
-
- defer func() {
- e := c.didexchangeClient.UnregisterMsgEvent(statusCh)
- if e != nil {
- logger.Warnf("Failed to unregister msg event for connect: %w", e)
- }
- }()
-
- opts := &connectOpts{}
- for _, opt := range options {
- opt(opts)
- }
-
- connID, err := c.oobClient.AcceptInvitation(invitation, opts.Label, getOobMessageOptions(opts)...)
- if err != nil {
- return "", fmt.Errorf("failed to accept invitation : %w", err)
- }
-
- if opts.timeout == 0 {
- opts.timeout = defaultDIDExchangeTimeOut
- }
-
- ctx, cancel := context.WithTimeout(context.Background(), opts.timeout)
- defer cancel()
-
- err = waitForConnect(ctx, statusCh, connID)
- if err != nil {
- return "", fmt.Errorf("wallet connect failed : %w", err)
- }
-
- return connID, nil
-}
-
-// ProposePresentation accepts out-of-band invitation and sends message proposing presentation
-// from wallet to relying party.
-// https://w3c-ccg.github.io/universal-wallet-interop-spec/#proposepresentation
-//
-// Currently Supporting
-// [0454-present-proof-v2](https://github.com/hyperledger/aries-rfcs/tree/master/features/0454-present-proof-v2)
-//
-// Args:
-// - authToken: authorization for performing operation.
-// - invitation: out-of-band invitation from relying party.
-// - options: options for accepting invitation and send propose presentation message.
-//
-// Returns:
-// - DIDCommMsgMap containing request presentation message if operation is successful.
-// - error if operation fails.
-//
-func (c *Wallet) ProposePresentation(authToken string, invitation *GenericInvitation, options ...InitiateInteractionOption) (*service.DIDCommMsgMap, error) { //nolint: lll
- opts := &initiateInteractionOpts{}
- for _, opt := range options {
- opt(opts)
- }
-
- var (
- connID string
- err error
- )
-
- switch invitation.Version() {
- default:
- fallthrough
- case service.V1:
- connID, err = c.Connect(authToken, (*outofband.Invitation)(invitation.AsV1()), opts.connectOpts...)
- if err != nil {
- return nil, fmt.Errorf("failed to perform did connection : %w", err)
- }
- case service.V2:
- connOpts := &connectOpts{}
-
- for _, opt := range opts.connectOpts {
- opt(connOpts)
- }
-
- connID, err = c.oobV2Client.AcceptInvitation(
- invitation.AsV2(),
- outofbandv2svc.WithRouterConnections(connOpts.Connections),
- )
- if err != nil {
- return nil, fmt.Errorf("failed to accept OOB v2 invitation : %w", err)
- }
- }
-
- connRecord, err := c.connectionLookup.GetConnectionRecord(connID)
- if err != nil {
- return nil, fmt.Errorf("failed to lookup connection for propose presentation : %w", err)
- }
-
- opts = prepareInteractionOpts(connRecord, opts)
-
- _, err = c.presentProofClient.SendProposePresentation(&presentproof.ProposePresentation{}, connRecord)
- if err != nil {
- return nil, fmt.Errorf("failed to propose presentation from wallet: %w", err)
- }
-
- ctx, cancel := context.WithTimeout(context.Background(), opts.timeout)
- defer cancel()
-
- return c.waitForRequestPresentation(ctx, connRecord)
-}
-
-// PresentProof sends message present proof message from wallet to relying party.
-// https://w3c-ccg.github.io/universal-wallet-interop-spec/#presentproof
-//
-// Currently Supporting
-// [0454-present-proof-v2](https://github.com/hyperledger/aries-rfcs/tree/master/features/0454-present-proof-v2)
-//
-// Args:
-// - authToken: authorization for performing operation.
-// - thID: thread ID (action ID) of request presentation.
-// - presentProofFrom: presentation to be sent.
-//
-// Returns:
-// - Credential interaction status containing status, redirectURL.
-// - error if operation fails.
-//
-func (c *Wallet) PresentProof(authToken, thID string, options ...ConcludeInteractionOptions) (*CredentialInteractionStatus, error) { //nolint: lll
- opts := &concludeInteractionOpts{}
-
- for _, option := range options {
- option(opts)
- }
-
- var presentation interface{}
- if opts.presentation != nil {
- presentation = opts.presentation
- } else {
- presentation = opts.rawPresentation
- }
-
- err := c.presentProofClient.AcceptRequestPresentation(thID, &presentproof.Presentation{
- Attachments: []decorator.GenericAttachment{{
- ID: uuid.New().String(),
- Data: decorator.AttachmentData{
- JSON: presentation,
- },
- }},
- }, nil)
- if err != nil {
- return nil, err
- }
-
- // wait for ack or problem-report.
- if opts.waitForDone {
- statusCh := make(chan service.StateMsg, msgEventBufferSize)
-
- err = c.presentProofClient.RegisterMsgEvent(statusCh)
- if err != nil {
- return nil, fmt.Errorf("failed to register present proof msg event : %w", err)
- }
-
- defer func() {
- e := c.presentProofClient.UnregisterMsgEvent(statusCh)
- if e != nil {
- logger.Warnf("Failed to unregister msg event for present proof: %w", e)
- }
- }()
-
- ctx, cancel := context.WithTimeout(context.Background(), opts.timeout)
- defer cancel()
-
- return waitCredInteractionCompletion(ctx, statusCh, thID)
- }
-
- return &CredentialInteractionStatus{Status: model.AckStatusPENDING}, nil
-}
-
-// ProposeCredential sends propose credential message from wallet to issuer.
-// https://w3c-ccg.github.io/universal-wallet-interop-spec/#proposecredential
-//
-// Currently Supporting : 0453-issueCredentialV2
-// https://github.com/hyperledger/aries-rfcs/blob/main/features/0453-issue-credential-v2/README.md
-//
-// Args:
-// - authToken: authorization for performing operation.
-// - invitation: out-of-band invitation from issuer.
-// - options: options for accepting invitation and send propose credential message.
-//
-// Returns:
-// - DIDCommMsgMap containing offer credential message if operation is successful.
-// - error if operation fails.
-//
-func (c *Wallet) ProposeCredential(authToken string, invitation *GenericInvitation, options ...InitiateInteractionOption) (*service.DIDCommMsgMap, error) { //nolint: lll
- opts := &initiateInteractionOpts{}
- for _, opt := range options {
- opt(opts)
- }
-
- var (
- connID string
- err error
- )
-
- switch invitation.Version() {
- default:
- fallthrough
- case service.V1:
- connID, err = c.Connect(authToken, (*outofband.Invitation)(invitation.AsV1()), opts.connectOpts...)
- if err != nil {
- return nil, fmt.Errorf("failed to perform did connection : %w", err)
- }
- case service.V2:
- connOpts := &connectOpts{}
-
- for _, opt := range opts.connectOpts {
- opt(connOpts)
- }
-
- connID, err = c.oobV2Client.AcceptInvitation(
- invitation.AsV2(),
- outofbandv2svc.WithRouterConnections(connOpts.Connections),
- )
- if err != nil {
- return nil, fmt.Errorf("failed to accept OOB v2 invitation : %w", err)
- }
- }
-
- connRecord, err := c.connectionLookup.GetConnectionRecord(connID)
- if err != nil {
- return nil, fmt.Errorf("failed to lookup connection for propose presentation : %w", err)
- }
-
- opts = prepareInteractionOpts(connRecord, opts)
-
- _, err = c.issueCredentialClient.SendProposal(
- &issuecredential.ProposeCredential{InvitationID: invitation.ID},
- connRecord,
- )
- if err != nil {
- return nil, fmt.Errorf("failed to propose credential from wallet: %w", err)
- }
-
- ctx, cancel := context.WithTimeout(context.Background(), opts.timeout)
- defer cancel()
-
- return c.waitForOfferCredential(ctx, connRecord)
-}
-
-// RequestCredential sends request credential message from wallet to issuer and
-// optionally waits for credential fulfillment.
-// https://w3c-ccg.github.io/universal-wallet-interop-spec/#requestcredential
-//
-// Currently Supporting : 0453-issueCredentialV2
-// https://github.com/hyperledger/aries-rfcs/blob/main/features/0453-issue-credential-v2/README.md
-//
-// Args:
-// - authToken: authorization for performing operation.
-// - thID: thread ID (action ID) of offer credential message previously received.
-// - concludeInteractionOptions: options to conclude interaction like presentation to be shared etc.
-//
-// Returns:
-// - Credential interaction status containing status, redirectURL.
-// - error if operation fails.
-//
-func (c *Wallet) RequestCredential(authToken, thID string, options ...ConcludeInteractionOptions) (*CredentialInteractionStatus, error) { //nolint: lll
- opts := &concludeInteractionOpts{}
-
- for _, option := range options {
- option(opts)
- }
-
- var presentation interface{}
- if opts.presentation != nil {
- presentation = opts.presentation
- } else {
- presentation = opts.rawPresentation
- }
-
- attachmentID := uuid.New().String()
-
- err := c.issueCredentialClient.AcceptOffer(thID, &issuecredential.RequestCredential{
- Type: issuecredentialsvc.RequestCredentialMsgTypeV2,
- Formats: []issuecredentialsvc.Format{{
- AttachID: attachmentID,
- Format: ldJSONMimeType,
- }},
- Attachments: []decorator.GenericAttachment{{
- ID: attachmentID,
- Data: decorator.AttachmentData{
- JSON: presentation,
- },
- }},
- })
- if err != nil {
- return nil, err
- }
-
- // wait for credential fulfillment.
- if opts.waitForDone {
- statusCh := make(chan service.StateMsg, msgEventBufferSize)
-
- err = c.issueCredentialClient.RegisterMsgEvent(statusCh)
- if err != nil {
- return nil, fmt.Errorf("failed to register issue credential action event : %w", err)
- }
-
- defer func() {
- e := c.issueCredentialClient.UnregisterMsgEvent(statusCh)
- if e != nil {
- logger.Warnf("Failed to unregister action event for issue credential: %w", e)
- }
- }()
-
- ctx, cancel := context.WithTimeout(context.Background(), opts.timeout)
- defer cancel()
-
- return waitCredInteractionCompletion(ctx, statusCh, thID)
- }
-
- return &CredentialInteractionStatus{Status: model.AckStatusPENDING}, nil
-}
-
// ResolveCredentialManifest resolves given credential manifest by credential fulfillment or credential.
// Supports: https://identity.foundation/credential-manifest/
//
@@ -1272,179 +846,6 @@ func (c *Wallet) validateVerificationMethod(didDoc *did.Doc, opts *ProofOptions,
return fmt.Errorf("unable to find '%s' for given verification method", supportedRelationships[relationship])
}
-// currently correlating response action by connection due to limitation in current present proof V1 implementation.
-func (c *Wallet) waitForRequestPresentation(ctx context.Context, record *connection.Record) (*service.DIDCommMsgMap, error) { //nolint: lll
- done := make(chan *service.DIDCommMsgMap)
-
- go func() {
- for {
- actions, err := c.presentProofClient.Actions()
- if err != nil {
- continue
- }
-
- if len(actions) > 0 {
- for _, action := range actions {
- if action.MyDID == record.MyDID && action.TheirDID == record.TheirDID {
- done <- &action.Msg
- return
- }
- }
- }
-
- select {
- default:
- time.Sleep(retryDelay)
- case <-ctx.Done():
- return
- }
- }
- }()
-
- select {
- case msg := <-done:
- return msg, nil
- case <-ctx.Done():
- return nil, fmt.Errorf("timeout waiting for request presentation message")
- }
-}
-
-// currently correlating response action by connection due to limitation in current issue credential V1 implementation.
-func (c *Wallet) waitForOfferCredential(ctx context.Context, record *connection.Record) (*service.DIDCommMsgMap, error) { //nolint: lll
- done := make(chan *service.DIDCommMsgMap)
-
- go func() {
- for {
- actions, err := c.issueCredentialClient.Actions()
- if err != nil {
- continue
- }
-
- if len(actions) > 0 {
- for _, action := range actions {
- if action.MyDID == record.MyDID && action.TheirDID == record.TheirDID {
- done <- &action.Msg
- return
- }
- }
- }
-
- select {
- default:
- time.Sleep(retryDelay)
- case <-ctx.Done():
- return
- }
- }
- }()
-
- select {
- case msg := <-done:
- return msg, nil
- case <-ctx.Done():
- return nil, fmt.Errorf("timeout waiting for offer credential message")
- }
-}
-
-func waitForConnect(ctx context.Context, didStateMsgs chan service.StateMsg, connID string) error {
- done := make(chan struct{})
-
- go func() {
- for msg := range didStateMsgs {
- if msg.Type != service.PostState || msg.StateID != didexchangeSvc.StateIDCompleted {
- continue
- }
-
- var event didexchangeSvc.Event
-
- switch p := msg.Properties.(type) {
- case didexchangeSvc.Event:
- event = p
- default:
- logger.Warnf("failed to cast didexchange event properties")
-
- continue
- }
-
- if event.ConnectionID() == connID {
- logger.Debugf(
- "Received connection complete event for invitationID=%s connectionID=%s",
- event.InvitationID(), event.ConnectionID())
-
- close(done)
-
- break
- }
- }
- }()
-
- select {
- case <-done:
- return nil
- case <-ctx.Done():
- return fmt.Errorf("time out waiting for did exchange state 'completed'")
- }
-}
-
-// wait for credential interaction to be completed (done or abandoned protocol state).
-func waitCredInteractionCompletion(ctx context.Context, didStateMsgs chan service.StateMsg, thID string) (*CredentialInteractionStatus, error) { // nolint:gocognit,gocyclo,lll
- done := make(chan *CredentialInteractionStatus)
-
- go func() {
- for msg := range didStateMsgs {
- // match post state.
- if msg.Type != service.PostState {
- continue
- }
-
- // invalid state msg.
- if msg.Msg == nil {
- continue
- }
-
- msgThID, err := msg.Msg.ThreadID()
- if err != nil {
- continue
- }
-
- // match parent thread ID.
- if msg.Msg.ParentThreadID() != thID && msgThID != thID {
- continue
- }
-
- // match protocol state.
- if msg.StateID != stateNameDone && msg.StateID != stateNameAbandoned && msg.StateID != stateNameAbandoning {
- continue
- }
-
- properties := msg.Properties.All()
-
- response := &CredentialInteractionStatus{}
- response.RedirectURL, response.Status = getWebRedirectInfo(properties)
-
- // if redirect status missing, then use protocol state, done -> OK, abandoned -> FAIL.
- if response.Status == "" {
- if msg.StateID == stateNameAbandoned || msg.StateID == stateNameAbandoning {
- response.Status = model.AckStatusFAIL
- } else {
- response.Status = model.AckStatusOK
- }
- }
-
- done <- response
-
- return
- }
- }()
-
- select {
- case status := <-done:
- return status, nil
- case <-ctx.Done():
- return nil, fmt.Errorf("time out waiting for credential interaction to get completed")
- }
-}
-
// addContext adds context if not found in given data model.
func addContext(v interface{}, ldcontext string) {
if vc, ok := v.(*verifiable.Credential); ok {
@@ -1472,30 +873,3 @@ func updateProfile(keyManager kms.KeyManager, profile *profile) error {
return nil
}
-
-func prepareInteractionOpts(connRecord *connection.Record, opts *initiateInteractionOpts) *initiateInteractionOpts {
- if opts.from == "" {
- opts.from = connRecord.TheirDID
- }
-
- if opts.timeout == 0 {
- opts.timeout = defaultWaitForRequestPresentationTimeOut
- }
-
- return opts
-}
-
-// getWebRedirectInfo reads web redirect info from properties.
-func getWebRedirectInfo(properties map[string]interface{}) (string, string) {
- var redirect, status string
-
- if redirectURL, ok := properties[webRedirectURLKey]; ok {
- redirect = redirectURL.(string) //nolint: errcheck, forcetypeassert
- }
-
- if redirectStatus, ok := properties[webRedirectStatusKey]; ok {
- status = redirectStatus.(string) //nolint: errcheck, forcetypeassert
- }
-
- return redirect, status
-}
diff --git a/pkg/wallet/wallet_test.go b/pkg/wallet/wallet_test.go
index 4385b3e46..d2dfb368b 100644
--- a/pkg/wallet/wallet_test.go
+++ b/pkg/wallet/wallet_test.go
@@ -20,45 +20,28 @@ import (
"time"
"github.com/btcsuite/btcutil/base58"
- "github.com/golang/mock/gomock"
"github.com/google/uuid"
"github.com/stretchr/testify/require"
"github.com/hyperledger/aries-framework-go/component/storage/edv"
"github.com/hyperledger/aries-framework-go/internal/testdata"
- "github.com/hyperledger/aries-framework-go/pkg/client/outofband"
"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/didcomm/common/model"
- "github.com/hyperledger/aries-framework-go/pkg/didcomm/common/service"
- "github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/didexchange"
- issuecredentialsvc "github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/issuecredential"
- "github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/mediator"
- outofbandSvc "github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/outofband"
- oobv2 "github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/outofbandv2"
- presentproofSvc "github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/presentproof"
"github.com/hyperledger/aries-framework-go/pkg/doc/did"
"github.com/hyperledger/aries-framework-go/pkg/doc/presexch"
"github.com/hyperledger/aries-framework-go/pkg/doc/util"
"github.com/hyperledger/aries-framework-go/pkg/doc/verifiable"
vdrapi "github.com/hyperledger/aries-framework-go/pkg/framework/aries/api/vdr"
- mockoutofbandv2 "github.com/hyperledger/aries-framework-go/pkg/internal/gomocks/client/outofbandv2"
"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/webkms"
cryptomock "github.com/hyperledger/aries-framework-go/pkg/mock/crypto"
- mockdidexchange "github.com/hyperledger/aries-framework-go/pkg/mock/didcomm/protocol/didexchange"
- mockissuecredential "github.com/hyperledger/aries-framework-go/pkg/mock/didcomm/protocol/issuecredential"
- mockmediator "github.com/hyperledger/aries-framework-go/pkg/mock/didcomm/protocol/mediator"
- mockoutofband "github.com/hyperledger/aries-framework-go/pkg/mock/didcomm/protocol/outofband"
- mockpresentproof "github.com/hyperledger/aries-framework-go/pkg/mock/didcomm/protocol/presentproof"
mockkms "github.com/hyperledger/aries-framework-go/pkg/mock/kms"
mockprovider "github.com/hyperledger/aries-framework-go/pkg/mock/provider"
"github.com/hyperledger/aries-framework-go/pkg/mock/secretlock"
mockstorage "github.com/hyperledger/aries-framework-go/pkg/mock/storage"
mockvdr "github.com/hyperledger/aries-framework-go/pkg/mock/vdr"
"github.com/hyperledger/aries-framework-go/pkg/secretlock/local/masterlock/pbkdf2"
- "github.com/hyperledger/aries-framework-go/pkg/store/connection"
"github.com/hyperledger/aries-framework-go/pkg/vdr/key"
"github.com/hyperledger/aries-framework-go/spi/storage"
)
@@ -88,8 +71,6 @@ const (
sampleEDVVaultID = "sample-edv-vault-id"
sampleEDVEncryptionKID = "sample-edv-encryption-kid"
sampleEDVMacKID = "sample-edv-mac-kid"
- exampleWebRedirect = "http://example.com/sample"
- sampleMsgComment = "sample mock msg"
)
func TestCreate(t *testing.T) {
@@ -461,60 +442,6 @@ func TestNew(t *testing.T) {
require.Empty(t, wallet)
require.Contains(t, err.Error(), sampleWalletErr)
})
-
- t.Run("test get wallet failure - present proof client initialize error", func(t *testing.T) {
- mockctx := newMockProvider(t)
- delete(mockctx.ServiceMap, presentproofSvc.Name)
-
- err := CreateProfile(sampleUserID, mockctx, WithPassphrase(samplePassPhrase))
- require.NoError(t, err)
-
- wallet, err := New(sampleUserID, mockctx)
- require.Error(t, err)
- require.Empty(t, wallet)
- require.Contains(t, err.Error(), "failed to initialize present proof client")
- })
-
- t.Run("test get wallet failure - oob client initialize error", func(t *testing.T) {
- mockctx := newMockProvider(t)
- delete(mockctx.ServiceMap, outofbandSvc.Name)
-
- err := CreateProfile(sampleUserID, mockctx, WithPassphrase(samplePassPhrase))
- require.NoError(t, err)
-
- wallet, err := New(sampleUserID, mockctx)
- require.Error(t, err)
- require.Empty(t, wallet)
- require.Contains(t, err.Error(), "failed to initialize out-of-band client")
- })
-
- t.Run("test get wallet failure - oob client initialize error", func(t *testing.T) {
- mockctx := newMockProvider(t)
- delete(mockctx.ServiceMap, didexchange.DIDExchange)
-
- err := CreateProfile(sampleUserID, mockctx, WithPassphrase(samplePassPhrase))
- require.NoError(t, err)
-
- wallet, err := New(sampleUserID, mockctx)
- require.Error(t, err)
- require.Empty(t, wallet)
- require.Contains(t, err.Error(), "failed to initialize didexchange client")
- })
-
- t.Run("test get wallet failure - connection lookup initialize error", func(t *testing.T) {
- mockctx := newMockProvider(t)
- mockStoreProvider := mockstorage.NewMockStoreProvider()
- mockStoreProvider.FailNamespace = "didexchange"
- mockctx.StorageProviderValue = mockStoreProvider
-
- err := CreateProfile(sampleUserID, mockctx, WithPassphrase(samplePassPhrase))
- require.NoError(t, err)
-
- wallet, err := New(sampleUserID, mockctx)
- require.Error(t, err)
- require.Empty(t, wallet)
- require.Contains(t, err.Error(), "failed to initialize connection lookup")
- })
}
func TestWallet_OpenClose(t *testing.T) {
@@ -2501,1745 +2428,169 @@ func TestWallet_CreateKeyPair(t *testing.T) {
})
}
-func TestWallet_Connect(t *testing.T) {
- sampleDIDCommUser := uuid.New().String()
+func TestWallet_ResolveCredentialManifest(t *testing.T) {
mockctx := newMockProvider(t)
- err := CreateProfile(sampleDIDCommUser, mockctx, WithPassphrase(samplePassPhrase))
- require.NoError(t, err)
-
- t.Run("test did connect success", func(t *testing.T) {
- sampleConnID := uuid.New().String()
+ user := uuid.New().String()
- oobSvc := &mockoutofband.MockOobService{
- AcceptInvitationHandle: func(*outofbandSvc.Invitation, outofbandSvc.Options) (string, error) {
- return sampleConnID, nil
- },
- }
- mockctx.ServiceMap[outofbandSvc.Name] = oobSvc
-
- didexSvc := &mockdidexchange.MockDIDExchangeSvc{
- RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
- ch <- service.StateMsg{
- Type: service.PostState,
- StateID: didexchange.StateIDCompleted,
- Properties: &mockdidexchange.MockEventProperties{ConnID: sampleConnID},
- }
+ // create a wallet
+ err := CreateProfile(user, mockctx, WithPassphrase(samplePassPhrase))
+ require.NoError(t, err)
- return nil
- },
- }
- mockctx.ServiceMap[didexchange.DIDExchange] = didexSvc
+ wallet, err := New(user, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, wallet)
- wallet, err := New(sampleDIDCommUser, mockctx)
- require.NoError(t, err)
- require.NotEmpty(t, wallet)
+ // get token
+ token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase), WithUnlockExpiry(500*time.Millisecond))
+ require.NoError(t, err)
+ require.NotEmpty(t, token)
- token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
- require.NoError(t, err)
- require.NotEmpty(t, token)
+ fulfillmentVP, err := verifiable.ParsePresentation(testdata.CredentialFulfillmentWithMultipleVCs,
+ verifiable.WithPresDisabledProofCheck(),
+ verifiable.WithPresJSONLDDocumentLoader(mockctx.JSONLDDocumentLoader()))
+ require.NoError(t, err)
- defer wallet.Close()
+ vc, err := verifiable.ParseCredential(testdata.SampleUDCVC,
+ verifiable.WithJSONLDDocumentLoader(mockctx.JSONLDDocumentLoader()))
+ require.NoError(t, err)
- connectionID, err := wallet.Connect(token, &outofband.Invitation{})
- require.NoError(t, err)
- require.Equal(t, sampleConnID, connectionID)
- })
+ require.NoError(t, wallet.Add(token, Credential, testdata.SampleUDCVC))
- t.Run("test did connect failure - accept invitation failure", func(t *testing.T) {
- oobSvc := &mockoutofband.MockOobService{
- AcceptInvitationHandle: func(*outofbandSvc.Invitation, outofbandSvc.Options) (string, error) {
- return "", fmt.Errorf(sampleWalletErr)
+ t.Run("Test Resolving credential manifests", func(t *testing.T) {
+ testTable := map[string]struct {
+ manifest []byte
+ resolve ResolveManifestOption
+ resultCount int
+ error string
+ }{
+ "testing resolve by raw credential fulfillment": {
+ manifest: testdata.CredentialManifestMultipleVCs,
+ resolve: ResolveRawFulfillment(testdata.CredentialFulfillmentWithMultipleVCs),
+ resultCount: 2,
},
- }
-
- mockctx.ServiceMap[outofbandSvc.Name] = oobSvc
-
- wallet, err := New(sampleDIDCommUser, mockctx)
- require.NoError(t, err)
- require.NotEmpty(t, wallet)
-
- token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
- require.NoError(t, err)
- require.NotEmpty(t, token)
-
- defer wallet.Close()
-
- connectionID, err := wallet.Connect(token, &outofband.Invitation{}, WithConnectTimeout(1*time.Millisecond))
- require.Error(t, err)
- require.Contains(t, err.Error(), sampleWalletErr)
- require.Contains(t, err.Error(), "failed to accept invitation")
- require.Empty(t, connectionID)
- })
-
- t.Run("test did connect failure - register event failure", func(t *testing.T) {
- didexSvc := &mockdidexchange.MockDIDExchangeSvc{
- RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
- return fmt.Errorf(sampleWalletErr)
+ "testing resolve by credential fulfillment": {
+ manifest: testdata.CredentialManifestMultipleVCs,
+ resolve: ResolveFulfillment(fulfillmentVP),
+ resultCount: 2,
},
- }
- mockctx.ServiceMap[didexchange.DIDExchange] = didexSvc
-
- wallet, err := New(sampleDIDCommUser, mockctx)
- require.NoError(t, err)
- require.NotEmpty(t, wallet)
-
- token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
- require.NoError(t, err)
- require.NotEmpty(t, token)
-
- defer wallet.Close()
-
- connectionID, err := wallet.Connect(token, &outofband.Invitation{}, WithConnectTimeout(1*time.Millisecond))
- require.Error(t, err)
- require.Contains(t, err.Error(), sampleWalletErr)
- require.Contains(t, err.Error(), "failed to register msg event")
- require.Empty(t, connectionID)
- })
-
- t.Run("test did connect failure - state not completed", func(t *testing.T) {
- mockctx.ServiceMap[outofbandSvc.Name] = &mockoutofband.MockOobService{}
- mockctx.ServiceMap[didexchange.DIDExchange] = &mockdidexchange.MockDIDExchangeSvc{}
-
- wallet, err := New(sampleDIDCommUser, mockctx)
- require.NoError(t, err)
- require.NotEmpty(t, wallet)
-
- token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
- require.NoError(t, err)
- require.NotEmpty(t, token)
-
- defer wallet.Close()
-
- connectionID, err := wallet.Connect(token, &outofband.Invitation{}, WithConnectTimeout(1*time.Millisecond))
- require.Error(t, err)
- require.Contains(t, err.Error(), "time out waiting for did exchange state 'completed'")
- require.Empty(t, connectionID)
- })
-
- t.Run("test did connect success - with warnings", func(t *testing.T) {
- sampleConnID := uuid.New().String()
-
- oobSvc := &mockoutofband.MockOobService{
- AcceptInvitationHandle: func(*outofbandSvc.Invitation, outofbandSvc.Options) (string, error) {
- return sampleConnID, nil
+ "testing resolve by raw credential": {
+ manifest: testdata.CredentialManifestMultipleVCs,
+ resolve: ResolveRawCredential("udc_output", testdata.SampleUDCVC),
+ resultCount: 1,
},
- }
- mockctx.ServiceMap[outofbandSvc.Name] = oobSvc
-
- didexSvc := &mockdidexchange.MockDIDExchangeSvc{
- RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
- ch <- service.StateMsg{
- Type: service.PreState,
- StateID: didexchange.StateIDCompleted,
- }
-
- ch <- service.StateMsg{
- Type: service.PostState,
- StateID: didexchange.StateIDCompleted,
- }
-
- ch <- service.StateMsg{
- Type: service.PostState,
- StateID: didexchange.StateIDCompleted,
- Properties: &mockdidexchange.MockEventProperties{ConnID: sampleConnID},
- }
-
- return nil
+ "testing resolve by credential": {
+ manifest: testdata.CredentialManifestMultipleVCs,
+ resolve: ResolveCredential("udc_output", vc),
+ resultCount: 1,
+ },
+ "testing resolve by credential ID": {
+ manifest: testdata.CredentialManifestMultipleVCs,
+ resolve: ResolveCredentialID("udc_output", vc.ID),
+ resultCount: 1,
+ },
+ "testing failure - resolve by empty resolve option": {
+ manifest: testdata.CredentialManifestMultipleVCs,
+ resolve: ResolveCredential("udc_output", nil),
+ resultCount: 0,
+ error: "invalid option",
+ },
+ "testing failure - resolve by invalid raw fulfillment": {
+ manifest: testdata.CredentialManifestMultipleVCs,
+ resolve: ResolveRawFulfillment([]byte("{}")),
+ resultCount: 0,
+ error: "verifiable presentation is not valid",
},
- UnregisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
- return fmt.Errorf(sampleWalletErr)
+ "testing failure - resolve by invalid raw credential": {
+ manifest: testdata.CredentialManifestMultipleVCs,
+ resolve: ResolveRawCredential("", []byte("{}")),
+ resultCount: 0,
+ error: "credential type of unknown structure",
+ },
+ "testing failure - invalid credential manifest": {
+ manifest: []byte("{}"),
+ resolve: ResolveFulfillment(fulfillmentVP),
+ resultCount: 0,
+ error: "invalid credential manifest",
+ },
+ "testing failure - resolve raw credential by invalid descriptor ID": {
+ manifest: testdata.CredentialManifestMultipleVCs,
+ resolve: ResolveRawCredential("invalid", testdata.SampleUDCVC),
+ resultCount: 0,
+ error: "unable to find matching descriptor",
+ },
+ "testing failure - resolve credential by invalid descriptor ID": {
+ manifest: testdata.CredentialManifestMultipleVCs,
+ resolve: ResolveCredential("invalid", vc),
+ resultCount: 0,
+ error: "unable to find matching descriptor",
+ },
+ "testing failure - resolve credential by invalid credential ID": {
+ manifest: testdata.CredentialManifestMultipleVCs,
+ resolve: ResolveCredentialID("udc_output", "incorrect"),
+ resultCount: 0,
+ error: "failed to get credential to resolve from wallet",
},
}
- mockctx.ServiceMap[didexchange.DIDExchange] = didexSvc
- wallet, err := New(sampleDIDCommUser, mockctx)
- require.NoError(t, err)
- require.NotEmpty(t, wallet)
+ t.Parallel()
- token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
- require.NoError(t, err)
- require.NotEmpty(t, token)
+ for testName, testData := range testTable {
+ t.Run(testName, func(t *testing.T) {
+ resolved, err := wallet.ResolveCredentialManifest(token, testData.manifest, testData.resolve)
- defer wallet.Close()
+ if testData.error != "" {
+ require.Error(t, err)
+ require.Contains(t, err.Error(), testData.error)
+ require.Len(t, resolved, testData.resultCount)
- connectionID, err := wallet.Connect(token, &outofband.Invitation{})
- require.NoError(t, err)
- require.Equal(t, sampleConnID, connectionID)
- })
+ return
+ }
- t.Run("test oob connect options", func(t *testing.T) {
- options := []ConnectOptions{
- WithConnectTimeout(10 * time.Second),
- WithRouterConnections("sample-conn"),
- WithMyLabel("sample-label"),
- WithReuseAnyConnection(true),
- WithReuseDID("sample-did"),
- }
+ require.NoError(t, err)
+ require.NotEmpty(t, resolved)
+ require.Len(t, resolved, testData.resultCount)
- opts := &connectOpts{}
- for _, opt := range options {
- opt(opts)
+ for _, result := range resolved {
+ require.NotEmpty(t, result.DescriptorID)
+ require.NotEmpty(t, result.Title)
+ require.NotEmpty(t, result.Properties)
+ }
+ })
}
-
- require.Equal(t, opts.timeout, 10*time.Second)
- require.Equal(t, opts.Connections[0], "sample-conn")
- require.Equal(t, opts.MyLabel(), "sample-label")
- require.Equal(t, opts.ReuseDID, "sample-did")
- require.True(t, opts.ReuseAny)
-
- require.Len(t, getOobMessageOptions(opts), 3)
})
}
-func TestWallet_ProposePresentation(t *testing.T) {
- sampleDIDCommUser := uuid.New().String()
- mockctx := newMockProvider(t)
- err := CreateProfile(sampleDIDCommUser, mockctx, WithPassphrase(samplePassPhrase))
- require.NoError(t, err)
-
- const (
- myDID = "did:mydid:123"
- theirDID = "did:theirdid:123"
- )
-
- t.Run("test propose presentation success - didcomm v1", func(t *testing.T) {
- sampleConnID := uuid.New().String()
+func newMockProvider(t *testing.T) *mockprovider.Provider {
+ t.Helper()
- oobSvc := &mockoutofband.MockOobService{
- AcceptInvitationHandle: func(*outofbandSvc.Invitation, outofbandSvc.Options) (string, error) {
- return sampleConnID, nil
- },
- }
- mockctx.ServiceMap[outofbandSvc.Name] = oobSvc
-
- didexSvc := &mockdidexchange.MockDIDExchangeSvc{
- RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
- ch <- service.StateMsg{
- Type: service.PostState,
- StateID: didexchange.StateIDCompleted,
- Properties: &mockdidexchange.MockEventProperties{ConnID: sampleConnID},
- }
+ loader, err := ldtestutil.DocumentLoader()
+ require.NoError(t, err)
- return nil
- },
- }
- mockctx.ServiceMap[didexchange.DIDExchange] = didexSvc
-
- thID := uuid.New().String()
-
- ppSvc := &mockpresentproof.MockPresentProofSvc{
- ActionsFunc: func() ([]presentproofSvc.Action, error) {
- return []presentproofSvc.Action{
- {
- PIID: thID,
- Msg: service.NewDIDCommMsgMap(&presentproofSvc.RequestPresentationV2{
- Comment: "mock msg",
- }),
- MyDID: myDID,
- TheirDID: theirDID,
- },
- }, nil
- },
- HandleFunc: func(service.DIDCommMsg) (string, error) {
- return thID, nil
- },
- }
+ return &mockprovider.Provider{
+ StorageProviderValue: mockstorage.NewMockStoreProvider(),
+ ProtocolStateStorageProviderValue: mockstorage.NewMockStoreProvider(),
+ DocumentLoaderValue: loader,
+ }
+}
- mockctx.ServiceMap[outofbandSvc.Name] = oobSvc
- mockctx.ServiceMap[presentproofSvc.Name] = ppSvc
+func createSampleProfile(t *testing.T, mockctx *mockprovider.Provider) {
+ err := CreateProfile(sampleUserID, mockctx, WithPassphrase(samplePassPhrase))
+ require.NoError(t, err)
- store, err := mockctx.StorageProvider().OpenStore(connection.Namespace)
- require.NoError(t, err)
+ wallet, err := New(sampleUserID, mockctx)
+ require.NoError(t, err)
+ require.NotEmpty(t, wallet)
+ require.NotEmpty(t, wallet.profile.MasterLockCipher)
+}
- record := &connection.Record{
- ConnectionID: sampleConnID,
- MyDID: myDID,
- TheirDID: theirDID,
- }
- recordBytes, err := json.Marshal(record)
+// adds credentials to wallet and returns handle for cleanup.
+func addCredentialsToWallet(t *testing.T, walletInstance *Wallet, auth string, vcs ...*verifiable.Credential) func() {
+ for _, vc := range vcs {
+ vcBytes, err := vc.MarshalJSON()
require.NoError(t, err)
- require.NoError(t, store.Put(fmt.Sprintf("conn_%s", sampleConnID), recordBytes))
-
- wallet, err := New(sampleDIDCommUser, mockctx)
- require.NoError(t, err)
- require.NotEmpty(t, wallet)
-
- token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
- require.NoError(t, err)
- require.NotEmpty(t, token)
-
- defer wallet.Close()
-
- invitation := GenericInvitation{}
- err = json.Unmarshal([]byte(`{
- "@id": "abc123",
- "@type": "https://didcomm.org/out-of-band/1.0/invitation"
- }`), &invitation)
- require.NoError(t, err)
-
- msg, err := wallet.ProposePresentation(token, &invitation,
- WithConnectOptions(WithConnectTimeout(1*time.Millisecond)))
- require.NoError(t, err)
- require.NotEmpty(t, msg)
-
- // empty invitation defaults to DIDComm v1
- msg, err = wallet.ProposePresentation(token, &GenericInvitation{},
- WithConnectOptions(WithConnectTimeout(1*time.Millisecond)))
- require.NoError(t, err)
- require.NotEmpty(t, msg)
-
- // invitation with unknown version defaults to DIDComm v1
- msg, err = wallet.ProposePresentation(token, &GenericInvitation{version: "unknown"},
- WithConnectOptions(WithConnectTimeout(1*time.Millisecond)))
- require.NoError(t, err)
- require.NotEmpty(t, msg)
- })
-
- t.Run("test propose presentation success - didcomm v2", func(t *testing.T) {
- sampleConnID := uuid.New().String()
-
- ctrl := gomock.NewController(t)
- defer ctrl.Finish()
-
- oobv2Svc := mockoutofbandv2.NewMockOobService(ctrl)
- oobv2Svc.EXPECT().AcceptInvitation(gomock.Any(), gomock.Any()).Return(sampleConnID, nil).AnyTimes()
-
- mockctx.ServiceMap[oobv2.Name] = oobv2Svc
-
- thID := uuid.New().String()
-
- ppSvc := &mockpresentproof.MockPresentProofSvc{
- ActionsFunc: func() ([]presentproofSvc.Action, error) {
- return []presentproofSvc.Action{
- {
- PIID: thID,
- Msg: service.NewDIDCommMsgMap(&presentproofSvc.RequestPresentationV3{
- Body: presentproofSvc.RequestPresentationV3Body{
- Comment: "mock msg",
- },
- }),
- MyDID: myDID,
- TheirDID: theirDID,
- },
- }, nil
- },
- HandleFunc: func(service.DIDCommMsg) (string, error) {
- return thID, nil
- },
- }
-
- mockctx.ServiceMap[presentproofSvc.Name] = ppSvc
-
- connRec, err := connection.NewRecorder(mockctx)
- require.NoError(t, err)
-
- record := &connection.Record{
- ConnectionID: sampleConnID,
- MyDID: myDID,
- TheirDID: theirDID,
- DIDCommVersion: service.V2,
- State: connection.StateNameCompleted,
- }
-
- err = connRec.SaveConnectionRecord(record)
- require.NoError(t, err)
-
- wallet, err := New(sampleDIDCommUser, mockctx)
- require.NoError(t, err)
- require.NotEmpty(t, wallet)
-
- token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
- require.NoError(t, err)
- require.NotEmpty(t, token)
-
- defer wallet.Close()
-
- invitation := GenericInvitation{}
- err = json.Unmarshal([]byte(`{
- "id": "abc123",
- "type": "https://didcomm.org/out-of-band/2.0/invitation"
- }`), &invitation)
- require.NoError(t, err)
-
- msg, err := wallet.ProposePresentation(token, &invitation,
- WithConnectOptions(WithConnectTimeout(1*time.Millisecond)))
- require.NoError(t, err)
- require.NotEmpty(t, msg)
- })
-
- t.Run("test propose presentation failure - did connect failure", func(t *testing.T) {
- didexSvc := &mockdidexchange.MockDIDExchangeSvc{
- RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
- return fmt.Errorf(sampleWalletErr)
- },
- }
- mockctx.ServiceMap[didexchange.DIDExchange] = didexSvc
-
- wallet, err := New(sampleDIDCommUser, mockctx)
- require.NoError(t, err)
- require.NotEmpty(t, wallet)
-
- token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
- require.NoError(t, err)
- require.NotEmpty(t, token)
-
- defer wallet.Close()
-
- msg, err := wallet.ProposePresentation(token, &GenericInvitation{})
- require.Error(t, err)
- require.Contains(t, err.Error(), sampleWalletErr)
- require.Contains(t, err.Error(), "failed to perform did connection")
- require.Empty(t, msg)
- })
-
- t.Run("test propose presentation failure - no connection found", func(t *testing.T) {
- sampleConnID := uuid.New().String()
-
- oobSvc := &mockoutofband.MockOobService{
- AcceptInvitationHandle: func(*outofbandSvc.Invitation, outofbandSvc.Options) (string, error) {
- return sampleConnID, nil
- },
- }
- mockctx.ServiceMap[outofbandSvc.Name] = oobSvc
-
- didexSvc := &mockdidexchange.MockDIDExchangeSvc{
- RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
- ch <- service.StateMsg{
- Type: service.PostState,
- StateID: didexchange.StateIDCompleted,
- Properties: &mockdidexchange.MockEventProperties{ConnID: sampleConnID},
- }
-
- return nil
- },
- }
- mockctx.ServiceMap[didexchange.DIDExchange] = didexSvc
-
- wallet, err := New(sampleDIDCommUser, mockctx)
- require.NoError(t, err)
- require.NotEmpty(t, wallet)
-
- token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
- require.NoError(t, err)
- require.NotEmpty(t, token)
-
- defer wallet.Close()
-
- msg, err := wallet.ProposePresentation(token, &GenericInvitation{})
- require.Error(t, err)
- require.Contains(t, err.Error(), "failed to lookup connection")
- require.Empty(t, msg)
- })
-
- t.Run("test propose presentation failure - failed to send", func(t *testing.T) {
- sampleConnID := uuid.New().String()
-
- oobSvc := &mockoutofband.MockOobService{
- AcceptInvitationHandle: func(*outofbandSvc.Invitation, outofbandSvc.Options) (string, error) {
- return sampleConnID, nil
- },
- }
- mockctx.ServiceMap[outofbandSvc.Name] = oobSvc
-
- didexSvc := &mockdidexchange.MockDIDExchangeSvc{
- RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
- ch <- service.StateMsg{
- Type: service.PostState,
- StateID: didexchange.StateIDCompleted,
- Properties: &mockdidexchange.MockEventProperties{ConnID: sampleConnID},
- }
-
- return nil
- },
- }
- mockctx.ServiceMap[didexchange.DIDExchange] = didexSvc
-
- ppSvc := &mockpresentproof.MockPresentProofSvc{
- HandleFunc: func(service.DIDCommMsg) (string, error) {
- return "", fmt.Errorf(sampleWalletErr)
- },
- HandleOutboundFunc: func(service.DIDCommMsg, string, string) (string, error) {
- return "", fmt.Errorf(sampleWalletErr)
- },
- }
- mockctx.ServiceMap[presentproofSvc.Name] = ppSvc
-
- store, err := mockctx.StorageProvider().OpenStore(connection.Namespace)
- require.NoError(t, err)
-
- record := &connection.Record{
- ConnectionID: sampleConnID,
- MyDID: myDID,
- TheirDID: theirDID,
- }
- recordBytes, err := json.Marshal(record)
- require.NoError(t, err)
- require.NoError(t, store.Put(fmt.Sprintf("conn_%s", sampleConnID), recordBytes))
-
- wallet, err := New(sampleDIDCommUser, mockctx)
- require.NoError(t, err)
- require.NotEmpty(t, wallet)
-
- token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
- require.NoError(t, err)
- require.NotEmpty(t, token)
-
- defer wallet.Close()
-
- msg, err := wallet.ProposePresentation(token, &GenericInvitation{})
- require.Error(t, err)
- require.Contains(t, err.Error(), sampleWalletErr)
- require.Contains(t, err.Error(), "failed to propose presentation from wallet")
- require.Empty(t, msg)
- })
-
- t.Run("test propose presentation failure - timeout waiting for presentation request", func(t *testing.T) {
- sampleConnID := uuid.New().String()
-
- oobSvc := &mockoutofband.MockOobService{
- AcceptInvitationHandle: func(*outofbandSvc.Invitation, outofbandSvc.Options) (string, error) {
- return sampleConnID, nil
- },
- }
- mockctx.ServiceMap[outofbandSvc.Name] = oobSvc
-
- didexSvc := &mockdidexchange.MockDIDExchangeSvc{
- RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
- ch <- service.StateMsg{
- Type: service.PostState,
- StateID: didexchange.StateIDCompleted,
- Properties: &mockdidexchange.MockEventProperties{ConnID: sampleConnID},
- }
-
- return nil
- },
- }
- mockctx.ServiceMap[didexchange.DIDExchange] = didexSvc
-
- ppSvc := &mockpresentproof.MockPresentProofSvc{
- HandleFunc: func(service.DIDCommMsg) (string, error) {
- return uuid.New().String(), nil
- },
- }
- mockctx.ServiceMap[presentproofSvc.Name] = ppSvc
-
- store, err := mockctx.StorageProvider().OpenStore(connection.Namespace)
- require.NoError(t, err)
-
- record := &connection.Record{
- ConnectionID: sampleConnID,
- MyDID: myDID,
- TheirDID: theirDID,
- }
- recordBytes, err := json.Marshal(record)
- require.NoError(t, err)
- require.NoError(t, store.Put(fmt.Sprintf("conn_%s", sampleConnID), recordBytes))
-
- wallet, err := New(sampleDIDCommUser, mockctx)
- require.NoError(t, err)
- require.NotEmpty(t, wallet)
-
- token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
- require.NoError(t, err)
- require.NotEmpty(t, token)
-
- defer wallet.Close()
-
- msg, err := wallet.ProposePresentation(token, &GenericInvitation{}, WithInitiateTimeout(600*time.Millisecond))
- require.Error(t, err)
- require.Contains(t, err.Error(), "timeout waiting for request presentation message")
- require.Empty(t, msg)
- })
-
- t.Run("test propose presentation failure - action error", func(t *testing.T) {
- sampleConnID := uuid.New().String()
-
- oobSvc := &mockoutofband.MockOobService{
- AcceptInvitationHandle: func(*outofbandSvc.Invitation, outofbandSvc.Options) (string, error) {
- return sampleConnID, nil
- },
- }
- mockctx.ServiceMap[outofbandSvc.Name] = oobSvc
-
- didexSvc := &mockdidexchange.MockDIDExchangeSvc{
- RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
- ch <- service.StateMsg{
- Type: service.PostState,
- StateID: didexchange.StateIDCompleted,
- Properties: &mockdidexchange.MockEventProperties{ConnID: sampleConnID},
- }
-
- return nil
- },
- }
- mockctx.ServiceMap[didexchange.DIDExchange] = didexSvc
-
- ppSvc := &mockpresentproof.MockPresentProofSvc{
- HandleFunc: func(service.DIDCommMsg) (string, error) {
- return uuid.New().String(), nil
- },
- ActionsFunc: func() ([]presentproofSvc.Action, error) {
- return nil, fmt.Errorf(sampleWalletErr)
- },
- }
- mockctx.ServiceMap[presentproofSvc.Name] = ppSvc
-
- store, err := mockctx.StorageProvider().OpenStore(connection.Namespace)
- require.NoError(t, err)
-
- record := &connection.Record{
- ConnectionID: sampleConnID,
- TheirDID: theirDID,
- }
- recordBytes, err := json.Marshal(record)
- require.NoError(t, err)
- require.NoError(t, store.Put(fmt.Sprintf("conn_%s", sampleConnID), recordBytes))
-
- wallet, err := New(sampleDIDCommUser, mockctx)
- require.NoError(t, err)
- require.NotEmpty(t, wallet)
-
- token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
- require.NoError(t, err)
- require.NotEmpty(t, token)
-
- defer wallet.Close()
-
- msg, err := wallet.ProposePresentation(token, &GenericInvitation{}, WithInitiateTimeout(1*time.Millisecond),
- WithFromDID("did:sample:from"))
- require.Error(t, err)
- require.Contains(t, err.Error(), "timeout waiting for request presentation message")
- require.Empty(t, msg)
- })
-
- t.Run("test propose presentation failure - oob v2 accept error", func(t *testing.T) {
- ctrl := gomock.NewController(t)
- defer ctrl.Finish()
-
- expectErr := fmt.Errorf("expected error")
-
- oobv2Svc := mockoutofbandv2.NewMockOobService(ctrl)
- oobv2Svc.EXPECT().AcceptInvitation(gomock.Any(), gomock.Any()).Return("", expectErr).AnyTimes()
-
- mockctx.ServiceMap[oobv2.Name] = oobv2Svc
-
- wallet, err := New(sampleDIDCommUser, mockctx)
- require.NoError(t, err)
- require.NotEmpty(t, wallet)
-
- token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
- require.NoError(t, err)
- require.NotEmpty(t, token)
-
- defer wallet.Close()
-
- invitation := GenericInvitation{}
- err = json.Unmarshal([]byte(`{
- "id": "abc123",
- "type": "https://didcomm.org/out-of-band/2.0/invitation"
- }`), &invitation)
- require.NoError(t, err)
-
- _, err = wallet.ProposePresentation(token, &invitation,
- WithConnectOptions(WithConnectTimeout(1*time.Millisecond)))
- require.Error(t, err)
- require.ErrorIs(t, err, expectErr)
- require.Contains(t, err.Error(), "failed to accept OOB v2 invitation")
- })
-}
-
-func TestWallet_PresentProof(t *testing.T) {
- sampleDIDCommUser := uuid.New().String()
- mockctx := newMockProvider(t)
- err := CreateProfile(sampleDIDCommUser, mockctx, WithPassphrase(samplePassPhrase))
- require.NoError(t, err)
-
- t.Run("test present proof success", func(t *testing.T) {
- wallet, err := New(sampleDIDCommUser, mockctx)
- require.NoError(t, err)
- require.NotEmpty(t, wallet)
-
- token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
- require.NoError(t, err)
- require.NotEmpty(t, token)
-
- defer wallet.Close()
-
- response, err := wallet.PresentProof(token, uuid.New().String(), FromPresentation(&verifiable.Presentation{}))
- require.NoError(t, err)
- require.NotEmpty(t, response)
- require.Equal(t, model.AckStatusPENDING, response.Status)
- })
-
- t.Run("test present proof success - wait for done with redirect", func(t *testing.T) {
- thID := uuid.New().String()
- mockPresentProofSvc := &mockpresentproof.MockPresentProofSvc{
- RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
- ch <- service.StateMsg{
- Type: service.PostState,
- StateID: presentproofSvc.StateNameDone,
- Properties: &mockdidexchange.MockEventProperties{
- Properties: map[string]interface{}{
- webRedirectStatusKey: model.AckStatusOK,
- webRedirectURLKey: exampleWebRedirect,
- },
- },
- Msg: &mockMsg{thID: thID},
- }
-
- return nil
- },
- }
- mockctx.ServiceMap[presentproofSvc.Name] = mockPresentProofSvc
-
- wallet, err := New(sampleDIDCommUser, mockctx)
- require.NoError(t, err)
- require.NotEmpty(t, wallet)
-
- token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
- require.NoError(t, err)
- require.NotEmpty(t, token)
-
- defer wallet.Close()
-
- response, err := wallet.PresentProof(token, thID, FromPresentation(&verifiable.Presentation{}),
- WaitForDone(1*time.Millisecond))
- require.NoError(t, err)
- require.NotEmpty(t, response)
- require.Equal(t, model.AckStatusOK, response.Status)
- require.Equal(t, exampleWebRedirect, response.RedirectURL)
- })
-
- t.Run("test present proof success - wait for abandoned with redirect", func(t *testing.T) {
- thID := uuid.New().String()
- mockPresentProofSvc := &mockpresentproof.MockPresentProofSvc{
- RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
- ch <- service.StateMsg{
- Type: service.PostState,
- StateID: presentproofSvc.StateNameAbandoned,
- Properties: &mockdidexchange.MockEventProperties{
- Properties: map[string]interface{}{
- webRedirectStatusKey: model.AckStatusFAIL,
- webRedirectURLKey: exampleWebRedirect,
- },
- },
- Msg: &mockMsg{thID: thID},
- }
-
- return nil
- },
- }
- mockctx.ServiceMap[presentproofSvc.Name] = mockPresentProofSvc
-
- wallet, err := New(sampleDIDCommUser, mockctx)
- require.NoError(t, err)
- require.NotEmpty(t, wallet)
-
- token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
- require.NoError(t, err)
- require.NotEmpty(t, token)
-
- defer wallet.Close()
-
- response, err := wallet.PresentProof(token, thID, FromPresentation(&verifiable.Presentation{}),
- WaitForDone(1*time.Millisecond))
- require.NoError(t, err)
- require.NotEmpty(t, response)
- require.Equal(t, model.AckStatusFAIL, response.Status)
- require.Equal(t, exampleWebRedirect, response.RedirectURL)
- })
-
- t.Run("test present proof success - wait for done no redirect", func(t *testing.T) {
- thID := uuid.New().String()
- mockPresentProofSvc := &mockpresentproof.MockPresentProofSvc{
- RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
- ch <- service.StateMsg{
- Type: service.PostState,
- StateID: presentproofSvc.StateNameDone,
- Properties: &mockdidexchange.MockEventProperties{},
- Msg: &mockMsg{thID: thID},
- }
-
- return nil
- },
- }
- mockctx.ServiceMap[presentproofSvc.Name] = mockPresentProofSvc
-
- wallet, err := New(sampleDIDCommUser, mockctx)
- require.NoError(t, err)
- require.NotEmpty(t, wallet)
-
- token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
- require.NoError(t, err)
- require.NotEmpty(t, token)
-
- defer wallet.Close()
-
- response, err := wallet.PresentProof(token, thID, FromPresentation(&verifiable.Presentation{}),
- WaitForDone(1*time.Millisecond))
- require.NoError(t, err)
- require.NotEmpty(t, response)
- require.Equal(t, model.AckStatusOK, response.Status)
- require.Empty(t, response.RedirectURL)
- })
-
- t.Run("test present proof failure - wait for abandoned no redirect", func(t *testing.T) {
- thID := uuid.New().String()
- mockPresentProofSvc := &mockpresentproof.MockPresentProofSvc{
- RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
- ch <- service.StateMsg{
- Type: service.PostState,
- StateID: presentproofSvc.StateNameAbandoned,
- Properties: &mockdidexchange.MockEventProperties{},
- Msg: &mockMsg{thID: thID},
- }
-
- return nil
- },
- }
- mockctx.ServiceMap[presentproofSvc.Name] = mockPresentProofSvc
-
- wallet, err := New(sampleDIDCommUser, mockctx)
- require.NoError(t, err)
- require.NotEmpty(t, wallet)
-
- token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
- require.NoError(t, err)
- require.NotEmpty(t, token)
-
- defer wallet.Close()
-
- response, err := wallet.PresentProof(token, thID, FromPresentation(&verifiable.Presentation{}),
- WaitForDone(1*time.Millisecond))
- require.NoError(t, err)
- require.NotEmpty(t, response)
- require.Equal(t, model.AckStatusFAIL, response.Status)
- require.Empty(t, response.RedirectURL)
- })
-
- t.Run("test present proof failure", func(t *testing.T) {
- ppSvc := &mockpresentproof.MockPresentProofSvc{
- ActionContinueFunc: func(string, ...presentproofSvc.Opt) error {
- return fmt.Errorf(sampleWalletErr)
- },
- }
-
- mockctx.ServiceMap[presentproofSvc.Name] = ppSvc
-
- wallet, err := New(sampleDIDCommUser, mockctx)
- require.NoError(t, err)
- require.NotEmpty(t, wallet)
-
- token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
- require.NoError(t, err)
- require.NotEmpty(t, token)
-
- defer wallet.Close()
-
- response, err := wallet.PresentProof(token, uuid.New().String(), FromRawPresentation([]byte("{}")))
- require.Error(t, err)
- require.Contains(t, err.Error(), sampleWalletErr)
- require.Empty(t, response)
- })
-
- t.Run("test present proof failure - failed to register message event", func(t *testing.T) {
- thID := uuid.New().String()
- mockPresentProofSvc := &mockpresentproof.MockPresentProofSvc{
- RegisterMsgEventErr: errors.New(sampleWalletErr),
- }
- mockctx.ServiceMap[presentproofSvc.Name] = mockPresentProofSvc
-
- wallet, err := New(sampleDIDCommUser, mockctx)
- require.NoError(t, err)
- require.NotEmpty(t, wallet)
-
- token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
- require.NoError(t, err)
- require.NotEmpty(t, token)
-
- defer wallet.Close()
-
- response, err := wallet.PresentProof(token, thID, FromPresentation(&verifiable.Presentation{}),
- WaitForDone(1*time.Millisecond))
- require.Error(t, err)
- require.Contains(t, err.Error(), sampleWalletErr)
- require.Empty(t, response)
- })
-
- t.Run("test present proof failure - wait for done timeout", func(t *testing.T) {
- thID := uuid.New().String()
- mockPresentProofSvc := &mockpresentproof.MockPresentProofSvc{
- RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
- ch <- service.StateMsg{
- Type: service.PreState,
- }
-
- ch <- service.StateMsg{
- Type: service.PostState,
- }
-
- ch <- service.StateMsg{
- Type: service.PostState,
- Msg: &mockMsg{thID: "invalid"},
- }
-
- ch <- service.StateMsg{
- Type: service.PostState,
- StateID: "invalid",
- Msg: &mockMsg{thID: thID, fail: errors.New(sampleWalletErr)},
- }
-
- ch <- service.StateMsg{
- Type: service.PostState,
- StateID: "invalid",
- Msg: &mockMsg{thID: thID},
- }
-
- return nil
- },
- UnregisterMsgEventErr: errors.New(sampleWalletErr),
- }
- mockctx.ServiceMap[presentproofSvc.Name] = mockPresentProofSvc
-
- wallet, err := New(sampleDIDCommUser, mockctx)
- require.NoError(t, err)
- require.NotEmpty(t, wallet)
-
- token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
- require.NoError(t, err)
- require.NotEmpty(t, token)
-
- defer wallet.Close()
-
- response, err := wallet.PresentProof(token, thID, FromPresentation(&verifiable.Presentation{}),
- WaitForDone(1*time.Millisecond))
- require.Error(t, err)
- require.Contains(t, err.Error(), "time out waiting for credential interaction to get completed")
- require.Empty(t, response)
- })
-}
-
-func TestWallet_ProposeCredential(t *testing.T) {
- sampleDIDCommUser := uuid.New().String()
- mockctx := newMockProvider(t)
- err := CreateProfile(sampleDIDCommUser, mockctx, WithPassphrase(samplePassPhrase))
- require.NoError(t, err)
-
- const (
- myDID = "did:mydid:123"
- theirDID = "did:theirdid:123"
- )
-
- t.Run("test propose credential success", func(t *testing.T) {
- sampleConnID := uuid.New().String()
-
- oobSvc := &mockoutofband.MockOobService{
- AcceptInvitationHandle: func(*outofbandSvc.Invitation, outofbandSvc.Options) (string, error) {
- return sampleConnID, nil
- },
- }
- mockctx.ServiceMap[outofbandSvc.Name] = oobSvc
-
- didexSvc := &mockdidexchange.MockDIDExchangeSvc{
- RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
- ch <- service.StateMsg{
- Type: service.PostState,
- StateID: didexchange.StateIDCompleted,
- Properties: &mockdidexchange.MockEventProperties{ConnID: sampleConnID},
- }
-
- return nil
- },
- }
- mockctx.ServiceMap[didexchange.DIDExchange] = didexSvc
-
- thID := uuid.New().String()
-
- icSvc := &mockissuecredential.MockIssueCredentialSvc{
- ActionsFunc: func() ([]issuecredentialsvc.Action, error) {
- return []issuecredentialsvc.Action{
- {
- PIID: thID,
- Msg: service.NewDIDCommMsgMap(&issuecredentialsvc.OfferCredentialV2{
- Comment: sampleMsgComment,
- }),
- MyDID: myDID,
- TheirDID: theirDID,
- },
- }, nil
- },
- HandleFunc: func(service.DIDCommMsg) (string, error) {
- return thID, nil
- },
- }
-
- mockctx.ServiceMap[outofbandSvc.Name] = oobSvc
- mockctx.ServiceMap[issuecredentialsvc.Name] = icSvc
-
- store, err := mockctx.StorageProvider().OpenStore(connection.Namespace)
- require.NoError(t, err)
-
- record := &connection.Record{
- ConnectionID: sampleConnID,
- MyDID: myDID,
- TheirDID: theirDID,
- }
- recordBytes, err := json.Marshal(record)
- require.NoError(t, err)
- require.NoError(t, store.Put(fmt.Sprintf("conn_%s", sampleConnID), recordBytes))
-
- wallet, err := New(sampleDIDCommUser, mockctx)
- require.NoError(t, err)
- require.NotEmpty(t, wallet)
-
- token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
- require.NoError(t, err)
- require.NotEmpty(t, token)
-
- defer wallet.Close()
-
- msg, err := wallet.ProposeCredential(token, &GenericInvitation{},
- WithConnectOptions(WithConnectTimeout(1*time.Millisecond)))
- require.NoError(t, err)
- require.NotEmpty(t, msg)
-
- offer := &issuecredentialsvc.OfferCredentialV2{}
-
- err = msg.Decode(offer)
- require.NoError(t, err)
- require.NotEmpty(t, offer)
- require.Equal(t, sampleMsgComment, offer.Comment)
- })
-
- t.Run("test propose credential failure - did connect failure", func(t *testing.T) {
- didexSvc := &mockdidexchange.MockDIDExchangeSvc{
- RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
- return fmt.Errorf(sampleWalletErr)
- },
- }
- mockctx.ServiceMap[didexchange.DIDExchange] = didexSvc
-
- wallet, err := New(sampleDIDCommUser, mockctx)
- require.NoError(t, err)
- require.NotEmpty(t, wallet)
-
- token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
- require.NoError(t, err)
- require.NotEmpty(t, token)
-
- defer wallet.Close()
-
- msg, err := wallet.ProposeCredential(token, &GenericInvitation{})
- require.Error(t, err)
- require.Contains(t, err.Error(), sampleWalletErr)
- require.Contains(t, err.Error(), "failed to perform did connection")
- require.Empty(t, msg)
- })
-
- t.Run("test propose credential failure - oobv2 accept error", func(t *testing.T) {
- ctrl := gomock.NewController(t)
- defer ctrl.Finish()
-
- expectErr := fmt.Errorf("expected error")
-
- oobv2Svc := mockoutofbandv2.NewMockOobService(ctrl)
- oobv2Svc.EXPECT().AcceptInvitation(gomock.Any(), gomock.Any()).Return("", expectErr).AnyTimes()
-
- mockctx.ServiceMap[oobv2.Name] = oobv2Svc
-
- wallet, err := New(sampleDIDCommUser, mockctx)
- require.NoError(t, err)
- require.NotEmpty(t, wallet)
-
- token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
- require.NoError(t, err)
- require.NotEmpty(t, token)
-
- defer wallet.Close()
-
- invitation := GenericInvitation{}
- err = json.Unmarshal([]byte(`{
- "id": "abc123",
- "type": "https://didcomm.org/out-of-band/2.0/invitation"
- }`), &invitation)
- require.NoError(t, err)
-
- _, err = wallet.ProposeCredential(token, &invitation,
- WithConnectOptions(WithConnectTimeout(1*time.Millisecond)))
- require.Error(t, err)
- require.ErrorIs(t, err, expectErr)
- require.Contains(t, err.Error(), "failed to accept OOB v2 invitation")
- })
-
- t.Run("test propose credential failure - no connection found", func(t *testing.T) {
- sampleConnID := uuid.New().String()
-
- oobSvc := &mockoutofband.MockOobService{
- AcceptInvitationHandle: func(*outofbandSvc.Invitation, outofbandSvc.Options) (string, error) {
- return sampleConnID, nil
- },
- }
- mockctx.ServiceMap[outofbandSvc.Name] = oobSvc
-
- didexSvc := &mockdidexchange.MockDIDExchangeSvc{
- RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
- ch <- service.StateMsg{
- Type: service.PostState,
- StateID: didexchange.StateIDCompleted,
- Properties: &mockdidexchange.MockEventProperties{ConnID: sampleConnID},
- }
-
- return nil
- },
- }
- mockctx.ServiceMap[didexchange.DIDExchange] = didexSvc
-
- wallet, err := New(sampleDIDCommUser, mockctx)
- require.NoError(t, err)
- require.NotEmpty(t, wallet)
-
- token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
- require.NoError(t, err)
- require.NotEmpty(t, token)
-
- defer wallet.Close()
-
- msg, err := wallet.ProposeCredential(token, &GenericInvitation{})
- require.Error(t, err)
- require.Contains(t, err.Error(), "failed to lookup connection")
- require.Empty(t, msg)
- })
-
- t.Run("test propose credential failure - failed to send", func(t *testing.T) {
- sampleConnID := uuid.New().String()
-
- oobSvc := &mockoutofband.MockOobService{
- AcceptInvitationHandle: func(*outofbandSvc.Invitation, outofbandSvc.Options) (string, error) {
- return sampleConnID, nil
- },
- }
- mockctx.ServiceMap[outofbandSvc.Name] = oobSvc
-
- didexSvc := &mockdidexchange.MockDIDExchangeSvc{
- RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
- ch <- service.StateMsg{
- Type: service.PostState,
- StateID: didexchange.StateIDCompleted,
- Properties: &mockdidexchange.MockEventProperties{ConnID: sampleConnID},
- }
-
- return nil
- },
- }
- mockctx.ServiceMap[didexchange.DIDExchange] = didexSvc
-
- icSvc := &mockissuecredential.MockIssueCredentialSvc{
- HandleFunc: func(service.DIDCommMsg) (string, error) {
- return "", fmt.Errorf(sampleWalletErr)
- },
- HandleOutboundFunc: func(service.DIDCommMsg, string, string) (string, error) {
- return "", fmt.Errorf(sampleWalletErr)
- },
- }
- mockctx.ServiceMap[issuecredentialsvc.Name] = icSvc
-
- store, err := mockctx.StorageProvider().OpenStore(connection.Namespace)
- require.NoError(t, err)
-
- record := &connection.Record{
- ConnectionID: sampleConnID,
- MyDID: myDID,
- TheirDID: theirDID,
- }
- recordBytes, err := json.Marshal(record)
- require.NoError(t, err)
- require.NoError(t, store.Put(fmt.Sprintf("conn_%s", sampleConnID), recordBytes))
-
- wallet, err := New(sampleDIDCommUser, mockctx)
- require.NoError(t, err)
- require.NotEmpty(t, wallet)
-
- token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
- require.NoError(t, err)
- require.NotEmpty(t, token)
-
- defer wallet.Close()
-
- msg, err := wallet.ProposeCredential(token, &GenericInvitation{})
- require.Error(t, err)
- require.Contains(t, err.Error(), sampleWalletErr)
- require.Contains(t, err.Error(), "failed to propose credential from wallet")
- require.Empty(t, msg)
- })
-
- t.Run("test propose credential failure - timeout waiting for offer credential msg", func(t *testing.T) {
- sampleConnID := uuid.New().String()
-
- oobSvc := &mockoutofband.MockOobService{
- AcceptInvitationHandle: func(*outofbandSvc.Invitation, outofbandSvc.Options) (string, error) {
- return sampleConnID, nil
- },
- }
- mockctx.ServiceMap[outofbandSvc.Name] = oobSvc
-
- didexSvc := &mockdidexchange.MockDIDExchangeSvc{
- RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
- ch <- service.StateMsg{
- Type: service.PostState,
- StateID: didexchange.StateIDCompleted,
- Properties: &mockdidexchange.MockEventProperties{ConnID: sampleConnID},
- }
-
- return nil
- },
- }
- mockctx.ServiceMap[didexchange.DIDExchange] = didexSvc
-
- icSvc := &mockissuecredential.MockIssueCredentialSvc{
- HandleFunc: func(service.DIDCommMsg) (string, error) {
- return uuid.New().String(), nil
- },
- }
- mockctx.ServiceMap[issuecredentialsvc.Name] = icSvc
-
- store, err := mockctx.StorageProvider().OpenStore(connection.Namespace)
- require.NoError(t, err)
-
- record := &connection.Record{
- ConnectionID: sampleConnID,
- MyDID: myDID,
- TheirDID: theirDID,
- }
- recordBytes, err := json.Marshal(record)
- require.NoError(t, err)
- require.NoError(t, store.Put(fmt.Sprintf("conn_%s", sampleConnID), recordBytes))
-
- wallet, err := New(sampleDIDCommUser, mockctx)
- require.NoError(t, err)
- require.NotEmpty(t, wallet)
-
- token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
- require.NoError(t, err)
- require.NotEmpty(t, token)
-
- defer wallet.Close()
-
- msg, err := wallet.ProposeCredential(token, &GenericInvitation{}, WithInitiateTimeout(600*time.Millisecond))
- require.Error(t, err)
- require.Contains(t, err.Error(), "timeout waiting for offer credential message")
- require.Empty(t, msg)
- })
-
- t.Run("test propose presentation failure - action error", func(t *testing.T) {
- sampleConnID := uuid.New().String()
-
- oobSvc := &mockoutofband.MockOobService{
- AcceptInvitationHandle: func(*outofbandSvc.Invitation, outofbandSvc.Options) (string, error) {
- return sampleConnID, nil
- },
- }
- mockctx.ServiceMap[outofbandSvc.Name] = oobSvc
-
- didexSvc := &mockdidexchange.MockDIDExchangeSvc{
- RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
- ch <- service.StateMsg{
- Type: service.PostState,
- StateID: didexchange.StateIDCompleted,
- Properties: &mockdidexchange.MockEventProperties{ConnID: sampleConnID},
- }
-
- return nil
- },
- }
- mockctx.ServiceMap[didexchange.DIDExchange] = didexSvc
-
- icSvc := &mockissuecredential.MockIssueCredentialSvc{
- HandleFunc: func(service.DIDCommMsg) (string, error) {
- return uuid.New().String(), nil
- },
- ActionsFunc: func() ([]issuecredentialsvc.Action, error) {
- return nil, fmt.Errorf(sampleWalletErr)
- },
- }
- mockctx.ServiceMap[issuecredentialsvc.Name] = icSvc
-
- store, err := mockctx.StorageProvider().OpenStore(connection.Namespace)
- require.NoError(t, err)
-
- record := &connection.Record{
- ConnectionID: sampleConnID,
- TheirDID: theirDID,
- }
- recordBytes, err := json.Marshal(record)
- require.NoError(t, err)
- require.NoError(t, store.Put(fmt.Sprintf("conn_%s", sampleConnID), recordBytes))
-
- wallet, err := New(sampleDIDCommUser, mockctx)
- require.NoError(t, err)
- require.NotEmpty(t, wallet)
-
- token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
- require.NoError(t, err)
- require.NotEmpty(t, token)
-
- defer wallet.Close()
-
- msg, err := wallet.ProposeCredential(token, &GenericInvitation{}, WithInitiateTimeout(1*time.Millisecond),
- WithFromDID("did:sample:from"))
- require.Error(t, err)
- require.Contains(t, err.Error(), "timeout waiting for offer credential message")
- require.Empty(t, msg)
- })
-}
-
-func TestWallet_RequestCredential(t *testing.T) {
- sampleDIDCommUser := uuid.New().String()
- mockctx := newMockProvider(t)
- err := CreateProfile(sampleDIDCommUser, mockctx, WithPassphrase(samplePassPhrase))
- require.NoError(t, err)
-
- t.Run("test request credential success", func(t *testing.T) {
- wallet, err := New(sampleDIDCommUser, mockctx)
- require.NoError(t, err)
- require.NotEmpty(t, wallet)
-
- token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
- require.NoError(t, err)
- require.NotEmpty(t, token)
-
- defer wallet.Close()
-
- response, err := wallet.RequestCredential(token, uuid.New().String(), FromPresentation(&verifiable.Presentation{}))
- require.NoError(t, err)
- require.NotEmpty(t, response)
- require.Equal(t, model.AckStatusPENDING, response.Status)
- })
-
- t.Run("test request credential success - wait for done with redirect", func(t *testing.T) {
- thID := uuid.New().String()
-
- icSvc := &mockissuecredential.MockIssueCredentialSvc{
- RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
- ch <- service.StateMsg{
- Type: service.PostState,
- StateID: stateNameDone,
- Properties: &mockdidexchange.MockEventProperties{
- Properties: map[string]interface{}{
- webRedirectStatusKey: model.AckStatusOK,
- webRedirectURLKey: exampleWebRedirect,
- },
- },
- Msg: &mockMsg{thID: thID},
- }
-
- return nil
- },
- }
- mockctx.ServiceMap[issuecredentialsvc.Name] = icSvc
-
- wallet, err := New(sampleDIDCommUser, mockctx)
- require.NoError(t, err)
- require.NotEmpty(t, wallet)
-
- token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
- require.NoError(t, err)
- require.NotEmpty(t, token)
-
- defer wallet.Close()
-
- response, err := wallet.RequestCredential(token, thID, FromPresentation(&verifiable.Presentation{}),
- WaitForDone(0))
- require.NoError(t, err)
- require.NotEmpty(t, response)
- require.Equal(t, model.AckStatusOK, response.Status)
- require.Equal(t, exampleWebRedirect, response.RedirectURL)
- })
-
- t.Run("test for request credential - wait for problem report with redirect", func(t *testing.T) {
- thID := uuid.New().String()
-
- icSvc := &mockissuecredential.MockIssueCredentialSvc{
- RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
- ch <- service.StateMsg{
- Type: service.PostState,
- StateID: stateNameAbandoned,
- Properties: &mockdidexchange.MockEventProperties{
- Properties: map[string]interface{}{
- webRedirectStatusKey: model.AckStatusFAIL,
- webRedirectURLKey: exampleWebRedirect,
- },
- },
- Msg: &mockMsg{thID: thID},
- }
-
- return nil
- },
- }
- mockctx.ServiceMap[issuecredentialsvc.Name] = icSvc
-
- wallet, err := New(sampleDIDCommUser, mockctx)
- require.NoError(t, err)
- require.NotEmpty(t, wallet)
-
- token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
- require.NoError(t, err)
- require.NotEmpty(t, token)
-
- defer wallet.Close()
-
- response, err := wallet.RequestCredential(token, thID, FromPresentation(&verifiable.Presentation{}),
- WaitForDone(1*time.Millisecond))
- require.NoError(t, err)
- require.NotEmpty(t, response)
- require.Equal(t, model.AckStatusFAIL, response.Status)
- require.Equal(t, exampleWebRedirect, response.RedirectURL)
- })
-
- t.Run("test request credential success - wait for done no redirect", func(t *testing.T) {
- thID := uuid.New().String()
-
- icSvc := &mockissuecredential.MockIssueCredentialSvc{
- RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
- ch <- service.StateMsg{
- Type: service.PostState,
- StateID: stateNameDone,
- Properties: &mockdidexchange.MockEventProperties{},
- Msg: &mockMsg{thID: thID},
- }
-
- return nil
- },
- }
- mockctx.ServiceMap[issuecredentialsvc.Name] = icSvc
-
- wallet, err := New(sampleDIDCommUser, mockctx)
- require.NoError(t, err)
- require.NotEmpty(t, wallet)
-
- token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
- require.NoError(t, err)
- require.NotEmpty(t, token)
-
- defer wallet.Close()
-
- response, err := wallet.RequestCredential(token, thID, FromPresentation(&verifiable.Presentation{}),
- WaitForDone(10*time.Millisecond))
- require.NoError(t, err)
- require.NotEmpty(t, response)
- require.Equal(t, model.AckStatusOK, response.Status)
- require.Empty(t, response.RedirectURL)
- })
-
- t.Run("test request credential failure - wait for problem report no redirect", func(t *testing.T) {
- thID := uuid.New().String()
-
- icSvc := &mockissuecredential.MockIssueCredentialSvc{
- RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
- ch <- service.StateMsg{
- Type: service.PostState,
- StateID: stateNameAbandoned,
- Properties: &mockdidexchange.MockEventProperties{},
- Msg: &mockMsg{thID: thID},
- }
-
- return nil
- },
- }
- mockctx.ServiceMap[issuecredentialsvc.Name] = icSvc
-
- wallet, err := New(sampleDIDCommUser, mockctx)
- require.NoError(t, err)
- require.NotEmpty(t, wallet)
-
- token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
- require.NoError(t, err)
- require.NotEmpty(t, token)
-
- defer wallet.Close()
-
- response, err := wallet.RequestCredential(token, thID, FromPresentation(&verifiable.Presentation{}),
- WaitForDone(1*time.Millisecond))
- require.NoError(t, err)
- require.NotEmpty(t, response)
- require.Equal(t, model.AckStatusFAIL, response.Status)
- require.Empty(t, response.RedirectURL)
- })
-
- t.Run("test request credential failure", func(t *testing.T) {
- icSvc := &mockissuecredential.MockIssueCredentialSvc{
- ActionContinueFunc: func(string, ...issuecredentialsvc.Opt) error {
- return fmt.Errorf(sampleWalletErr)
- },
- }
- mockctx.ServiceMap[issuecredentialsvc.Name] = icSvc
-
- wallet, err := New(sampleDIDCommUser, mockctx)
- require.NoError(t, err)
- require.NotEmpty(t, wallet)
-
- token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
- require.NoError(t, err)
- require.NotEmpty(t, token)
-
- defer wallet.Close()
-
- response, err := wallet.RequestCredential(token, uuid.New().String(), FromRawPresentation([]byte("{}")))
- require.Error(t, err)
- require.Contains(t, err.Error(), sampleWalletErr)
- require.Empty(t, response)
- })
-
- t.Run("test request credential failure - failed to register msg event", func(t *testing.T) {
- thID := uuid.New().String()
- icSvc := &mockissuecredential.MockIssueCredentialSvc{
- RegisterMsgEventErr: errors.New(sampleWalletErr),
- }
- mockctx.ServiceMap[issuecredentialsvc.Name] = icSvc
-
- wallet, err := New(sampleDIDCommUser, mockctx)
- require.NoError(t, err)
- require.NotEmpty(t, wallet)
-
- token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
- require.NoError(t, err)
- require.NotEmpty(t, token)
-
- defer wallet.Close()
-
- response, err := wallet.RequestCredential(token, thID, FromPresentation(&verifiable.Presentation{}),
- WaitForDone(1*time.Millisecond))
- require.Error(t, err)
- require.Contains(t, err.Error(), sampleWalletErr)
- require.Empty(t, response)
- })
-
- t.Run("test request credential success - wait for done timeout", func(t *testing.T) {
- thID := uuid.New().String()
-
- icSvc := &mockissuecredential.MockIssueCredentialSvc{
- RegisterMsgEventHandle: func(ch chan<- service.StateMsg) error {
- ch <- service.StateMsg{
- Type: service.PreState,
- }
-
- ch <- service.StateMsg{
- Type: service.PostState,
- }
-
- ch <- service.StateMsg{
- Type: service.PostState,
- Msg: &mockMsg{thID: "invalid"},
- }
-
- ch <- service.StateMsg{
- Type: service.PostState,
- StateID: "invalid",
- Msg: &mockMsg{thID: thID, fail: errors.New(sampleWalletErr)},
- }
-
- ch <- service.StateMsg{
- Type: service.PostState,
- StateID: "invalid",
- Msg: &mockMsg{thID: thID},
- }
-
- return nil
- },
- UnregisterMsgEventErr: errors.New(sampleWalletErr),
- }
- mockctx.ServiceMap[issuecredentialsvc.Name] = icSvc
-
- wallet, err := New(sampleDIDCommUser, mockctx)
- require.NoError(t, err)
- require.NotEmpty(t, wallet)
-
- token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase))
- require.NoError(t, err)
- require.NotEmpty(t, token)
-
- defer wallet.Close()
-
- response, err := wallet.RequestCredential(token, thID, FromPresentation(&verifiable.Presentation{}),
- WaitForDone(700*time.Millisecond))
- require.Error(t, err)
- require.Contains(t, err.Error(), "time out waiting for credential interaction to get completed")
- require.Empty(t, response)
- })
-}
-
-func TestWallet_ResolveCredentialManifest(t *testing.T) {
- mockctx := newMockProvider(t)
- user := uuid.New().String()
-
- // create a wallet
- err := CreateProfile(user, mockctx, WithPassphrase(samplePassPhrase))
- require.NoError(t, err)
-
- wallet, err := New(user, mockctx)
- require.NoError(t, err)
- require.NotEmpty(t, wallet)
-
- // get token
- token, err := wallet.Open(WithUnlockByPassphrase(samplePassPhrase), WithUnlockExpiry(500*time.Millisecond))
- require.NoError(t, err)
- require.NotEmpty(t, token)
-
- fulfillmentVP, err := verifiable.ParsePresentation(testdata.CredentialFulfillmentWithMultipleVCs,
- verifiable.WithPresDisabledProofCheck(),
- verifiable.WithPresJSONLDDocumentLoader(mockctx.JSONLDDocumentLoader()))
- require.NoError(t, err)
-
- vc, err := verifiable.ParseCredential(testdata.SampleUDCVC,
- verifiable.WithJSONLDDocumentLoader(mockctx.JSONLDDocumentLoader()))
- require.NoError(t, err)
-
- require.NoError(t, wallet.Add(token, Credential, testdata.SampleUDCVC))
-
- t.Run("Test Resolving credential manifests", func(t *testing.T) {
- testTable := map[string]struct {
- manifest []byte
- resolve ResolveManifestOption
- resultCount int
- error string
- }{
- "testing resolve by raw credential fulfillment": {
- manifest: testdata.CredentialManifestMultipleVCs,
- resolve: ResolveRawFulfillment(testdata.CredentialFulfillmentWithMultipleVCs),
- resultCount: 2,
- },
- "testing resolve by credential fulfillment": {
- manifest: testdata.CredentialManifestMultipleVCs,
- resolve: ResolveFulfillment(fulfillmentVP),
- resultCount: 2,
- },
- "testing resolve by raw credential": {
- manifest: testdata.CredentialManifestMultipleVCs,
- resolve: ResolveRawCredential("udc_output", testdata.SampleUDCVC),
- resultCount: 1,
- },
- "testing resolve by credential": {
- manifest: testdata.CredentialManifestMultipleVCs,
- resolve: ResolveCredential("udc_output", vc),
- resultCount: 1,
- },
- "testing resolve by credential ID": {
- manifest: testdata.CredentialManifestMultipleVCs,
- resolve: ResolveCredentialID("udc_output", vc.ID),
- resultCount: 1,
- },
- "testing failure - resolve by empty resolve option": {
- manifest: testdata.CredentialManifestMultipleVCs,
- resolve: ResolveCredential("udc_output", nil),
- resultCount: 0,
- error: "invalid option",
- },
- "testing failure - resolve by invalid raw fulfillment": {
- manifest: testdata.CredentialManifestMultipleVCs,
- resolve: ResolveRawFulfillment([]byte("{}")),
- resultCount: 0,
- error: "verifiable presentation is not valid",
- },
- "testing failure - resolve by invalid raw credential": {
- manifest: testdata.CredentialManifestMultipleVCs,
- resolve: ResolveRawCredential("", []byte("{}")),
- resultCount: 0,
- error: "credential type of unknown structure",
- },
- "testing failure - invalid credential manifest": {
- manifest: []byte("{}"),
- resolve: ResolveFulfillment(fulfillmentVP),
- resultCount: 0,
- error: "invalid credential manifest",
- },
- "testing failure - resolve raw credential by invalid descriptor ID": {
- manifest: testdata.CredentialManifestMultipleVCs,
- resolve: ResolveRawCredential("invalid", testdata.SampleUDCVC),
- resultCount: 0,
- error: "unable to find matching descriptor",
- },
- "testing failure - resolve credential by invalid descriptor ID": {
- manifest: testdata.CredentialManifestMultipleVCs,
- resolve: ResolveCredential("invalid", vc),
- resultCount: 0,
- error: "unable to find matching descriptor",
- },
- "testing failure - resolve credential by invalid credential ID": {
- manifest: testdata.CredentialManifestMultipleVCs,
- resolve: ResolveCredentialID("udc_output", "incorrect"),
- resultCount: 0,
- error: "failed to get credential to resolve from wallet",
- },
- }
-
- t.Parallel()
-
- for testName, testData := range testTable {
- t.Run(testName, func(t *testing.T) {
- resolved, err := wallet.ResolveCredentialManifest(token, testData.manifest, testData.resolve)
-
- if testData.error != "" {
- require.Error(t, err)
- require.Contains(t, err.Error(), testData.error)
- require.Len(t, resolved, testData.resultCount)
-
- return
- }
-
- require.NoError(t, err)
- require.NotEmpty(t, resolved)
- require.Len(t, resolved, testData.resultCount)
-
- for _, result := range resolved {
- require.NotEmpty(t, result.DescriptorID)
- require.NotEmpty(t, result.Title)
- require.NotEmpty(t, result.Properties)
- }
- })
- }
- })
-}
-
-func newMockProvider(t *testing.T) *mockprovider.Provider {
- t.Helper()
-
- loader, err := ldtestutil.DocumentLoader()
- require.NoError(t, err)
-
- serviceMap := map[string]interface{}{
- presentproofSvc.Name: &mockpresentproof.MockPresentProofSvc{},
- outofbandSvc.Name: &mockoutofband.MockOobService{},
- didexchange.DIDExchange: &mockdidexchange.MockDIDExchangeSvc{},
- mediator.Coordination: &mockmediator.MockMediatorSvc{},
- issuecredentialsvc.Name: &mockissuecredential.MockIssueCredentialSvc{},
- oobv2.Name: &mockoutofbandv2.MockOobService{},
- }
-
- return &mockprovider.Provider{
- StorageProviderValue: mockstorage.NewMockStoreProvider(),
- ProtocolStateStorageProviderValue: mockstorage.NewMockStoreProvider(),
- DocumentLoaderValue: loader,
- ServiceMap: serviceMap,
- }
-}
-
-func createSampleProfile(t *testing.T, mockctx *mockprovider.Provider) {
- err := CreateProfile(sampleUserID, mockctx, WithPassphrase(samplePassPhrase))
- require.NoError(t, err)
-
- wallet, err := New(sampleUserID, mockctx)
- require.NoError(t, err)
- require.NotEmpty(t, wallet)
- require.NotEmpty(t, wallet.profile.MasterLockCipher)
-}
-
-// adds credentials to wallet and returns handle for cleanup.
-func addCredentialsToWallet(t *testing.T, walletInstance *Wallet, auth string, vcs ...*verifiable.Credential) func() {
- for _, vc := range vcs {
- vcBytes, err := vc.MarshalJSON()
- require.NoError(t, err)
- require.NoError(t, walletInstance.Remove(auth, Credential, vc.ID))
- require.NoError(t, walletInstance.Add(auth, Credential, vcBytes))
- }
+ require.NoError(t, walletInstance.Remove(auth, Credential, vc.ID))
+ require.NoError(t, walletInstance.Add(auth, Credential, vcBytes))
+ }
return func() {
for _, vc := range vcs {
@@ -4250,31 +2601,3 @@ func addCredentialsToWallet(t *testing.T, walletInstance *Wallet, auth string, v
}
}
}
-
-// mockMsg containing custom parent thread ID.
-type mockMsg struct {
- *service.DIDCommMsgMap
- thID string
- fail error
- msgType string
-}
-
-func (m *mockMsg) ParentThreadID() string {
- return m.thID
-}
-
-func (m *mockMsg) ThreadID() (string, error) {
- return m.thID, m.fail
-}
-
-func (m *mockMsg) Type() string {
- if m.msgType != "" {
- return m.msgType
- }
-
- if m.DIDCommMsgMap != nil {
- return m.DIDCommMsgMap.Type()
- }
-
- return ""
-}
From 12e93a0fca506384a70d2c7dc7f0c1d74478b31d Mon Sep 17 00:00:00 2001
From: Abdulbois <30406506+Abdulbois@users.noreply.github.com>
Date: Wed, 13 Jul 2022 11:10:05 +0500
Subject: [PATCH 51/54] feat: Legacy Anoncrypt(RFC-0019) DIDComm v1
implementation (#3268)
* feat: Legacy Anoncrypt(RFC-0019) DIDComm v1 implementation
Signed-off-by: Abdulbois
* refactor: change copyright title
Signed-off-by: Abdulbois
* fix: golang-ci lint errors
Signed-off-by: Abdulbois
* fix: golang-ci lint errors
Signed-off-by: Abdulbois
---
.../packer/legacy/anoncrypt/anoncrypt.go | 86 +++
.../packer/legacy/anoncrypt/anoncrypt_test.go | 627 ++++++++++++++++++
pkg/didcomm/packer/legacy/anoncrypt/pack.go | 148 +++++
pkg/didcomm/packer/legacy/anoncrypt/unpack.go | 165 +++++
4 files changed, 1026 insertions(+)
create mode 100644 pkg/didcomm/packer/legacy/anoncrypt/anoncrypt.go
create mode 100644 pkg/didcomm/packer/legacy/anoncrypt/anoncrypt_test.go
create mode 100644 pkg/didcomm/packer/legacy/anoncrypt/pack.go
create mode 100644 pkg/didcomm/packer/legacy/anoncrypt/unpack.go
diff --git a/pkg/didcomm/packer/legacy/anoncrypt/anoncrypt.go b/pkg/didcomm/packer/legacy/anoncrypt/anoncrypt.go
new file mode 100644
index 000000000..e3a0b49c5
--- /dev/null
+++ b/pkg/didcomm/packer/legacy/anoncrypt/anoncrypt.go
@@ -0,0 +1,86 @@
+/*
+Copyright Avast Software. All Rights Reserved.
+
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package anoncryt
+
+import (
+ "crypto/rand"
+ "io"
+
+ "github.com/hyperledger/aries-framework-go/pkg/didcomm/packer"
+ "github.com/hyperledger/aries-framework-go/pkg/kms"
+ "github.com/hyperledger/aries-framework-go/pkg/kms/localkms"
+ "github.com/hyperledger/aries-framework-go/pkg/kms/webkms"
+)
+
+// Packer represents an Anoncrypt Pack/Unpacker that outputs/reads legacy Aries envelopes.
+type Packer struct {
+ randSource io.Reader
+ kms kms.KeyManager
+}
+
+// encodingType is the `typ` string identifier in a message that identifies the format as being legacy.
+const encodingType string = "JWM/1.0"
+
+// Anoncrypt type.
+const anonCrypt string = "Anoncrypt"
+
+// Anoncrypt encryption type format.
+const anonCryptEncType string = "chacha20poly1305_ietf"
+
+// New will create a Packer that encrypts messages using the legacy Aries format.
+// Note: legacy Packer does not support XChacha20Poly1035 (XC20P), only Chacha20Poly1035 (C20P).
+func New(ctx packer.Provider) *Packer {
+ k := ctx.KMS()
+
+ return &Packer{
+ randSource: rand.Reader,
+ kms: k,
+ }
+}
+
+// legacyEnvelope is the full payload envelope for the JSON message.
+type legacyEnvelope struct {
+ Protected string `json:"protected,omitempty"`
+ IV string `json:"iv,omitempty"`
+ CipherText string `json:"ciphertext,omitempty"`
+ Tag string `json:"tag,omitempty"`
+}
+
+// protected is the protected header of the JSON envelope.
+type protected struct {
+ Enc string `json:"enc,omitempty"`
+ Typ string `json:"typ,omitempty"`
+ Alg string `json:"alg,omitempty"`
+ Recipients []recipient `json:"recipients,omitempty"`
+}
+
+// recipient holds the data for a recipient in the envelope header.
+type recipient struct {
+ EncryptedKey string `json:"encrypted_key,omitempty"`
+ Header recipientHeader `json:"header,omitempty"`
+}
+
+// recipientHeader holds the header data for a recipient.
+type recipientHeader struct {
+ KID string `json:"kid,omitempty"`
+}
+
+// EncodingType returns the type of the encoding, as in the `Typ` field of the envelope header.
+func (p *Packer) EncodingType() string {
+ return encodingType
+}
+
+func newCryptoBox(manager kms.KeyManager) (kms.CryptoBox, error) {
+ switch manager.(type) {
+ case *localkms.LocalKMS:
+ return localkms.NewCryptoBox(manager)
+ case *webkms.RemoteKMS:
+ return webkms.NewCryptoBox(manager)
+ default:
+ return localkms.NewCryptoBox(manager)
+ }
+}
diff --git a/pkg/didcomm/packer/legacy/anoncrypt/anoncrypt_test.go b/pkg/didcomm/packer/legacy/anoncrypt/anoncrypt_test.go
new file mode 100644
index 000000000..d064a64a1
--- /dev/null
+++ b/pkg/didcomm/packer/legacy/anoncrypt/anoncrypt_test.go
@@ -0,0 +1,627 @@
+/*
+Copyright Avast Software. All Rights Reserved.
+
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package anoncryt
+
+import (
+ "crypto/ed25519"
+ "crypto/rand"
+ "encoding/base64"
+ "errors"
+ "fmt"
+ "io"
+ insecurerand "math/rand"
+ "testing"
+
+ "github.com/btcsuite/btcutil/base58"
+ "github.com/stretchr/testify/require"
+
+ cryptoapi "github.com/hyperledger/aries-framework-go/pkg/crypto"
+ "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto"
+ "github.com/hyperledger/aries-framework-go/pkg/didcomm/transport"
+ vdrapi "github.com/hyperledger/aries-framework-go/pkg/framework/aries/api/vdr"
+ "github.com/hyperledger/aries-framework-go/pkg/kms"
+ "github.com/hyperledger/aries-framework-go/pkg/kms/localkms"
+ "github.com/hyperledger/aries-framework-go/pkg/kms/webkms"
+ mockkms "github.com/hyperledger/aries-framework-go/pkg/mock/kms"
+ mockStorage "github.com/hyperledger/aries-framework-go/pkg/mock/storage"
+ "github.com/hyperledger/aries-framework-go/pkg/secretlock"
+ "github.com/hyperledger/aries-framework-go/pkg/secretlock/noop"
+ "github.com/hyperledger/aries-framework-go/spi/storage"
+)
+
+// failReader wraps a Reader, used for testing different failure checks for encryption tests.
+// count: count the number of Reads called before the failWriter fails.
+type failReader struct {
+ count int
+ data io.Reader
+}
+
+// newFailReader constructs a failWriter.
+func newFailReader(numSuccesses int, reader io.Reader) *failReader {
+ fw := failReader{numSuccesses, reader}
+ return &fw
+}
+
+// Write will count down a counter, with each call, and fail when the counter is 0
+// It calls the wrapped Writer until it's time to fail, after which all calls fail.
+// Note: the wrapped Writer can still return errors.
+func (fw *failReader) Read(out []byte) (int, error) {
+ if fw.count <= 0 {
+ // panic(fw)
+ return 0, errors.New("mock Reader has failed intentionally")
+ }
+
+ fw.count--
+
+ return fw.data.Read(out)
+}
+
+type provider struct {
+ storeProvider storage.Provider
+ kms kms.KeyManager
+ secretLock secretlock.Service
+ cryptoService cryptoapi.Crypto
+}
+
+func (p *provider) StorageProvider() storage.Provider {
+ return p.storeProvider
+}
+
+func (p *provider) Crypto() cryptoapi.Crypto {
+ return p.cryptoService
+}
+
+func newKMS(t *testing.T) (kms.KeyManager, storage.Store) {
+ msp := mockStorage.NewMockStoreProvider()
+ p := &provider{storeProvider: msp, secretLock: &noop.NoLock{}}
+
+ store, err := p.StorageProvider().OpenStore("test-kms")
+ require.NoError(t, err)
+
+ customKMS, err := localkms.New("local-lock://primary/test/", p)
+ require.NoError(t, err)
+
+ return customKMS, store
+}
+
+func persistKey(t *testing.T, pub, priv string, km kms.KeyManager) error {
+ t.Helper()
+
+ kid, err := localkms.CreateKID(base58.Decode(pub), kms.ED25519Type)
+ if err != nil {
+ return err
+ }
+
+ edPriv := ed25519.PrivateKey(base58.Decode(priv))
+ if len(edPriv) == 0 {
+ return fmt.Errorf("error converting bad public key")
+ }
+
+ k1, _, err := km.ImportPrivateKey(edPriv, kms.ED25519Type, kms.WithKeyID(kid))
+ require.NoError(t, err)
+ require.Equal(t, kid, k1)
+
+ return nil
+}
+
+func (p *provider) KMS() kms.KeyManager {
+ return p.kms
+}
+
+func newWithKMSAndCrypto(t *testing.T, k kms.KeyManager) *Packer {
+ c, err := tinkcrypto.New()
+ require.NoError(t, err)
+
+ return New(&provider{
+ kms: k,
+ cryptoService: c,
+ })
+}
+
+func (p *provider) SecretLock() secretlock.Service {
+ return p.secretLock
+}
+
+func (p *provider) VDRegistry() vdrapi.Registry {
+ return nil
+}
+
+func createKey(t *testing.T, km kms.KeyManager) []byte {
+ _, key, err := km.CreateAndExportPubKeyBytes(kms.ED25519Type)
+ require.NoError(t, err)
+
+ return key
+}
+
+func TestEncodingType(t *testing.T) {
+ testKMS, store := newKMS(t)
+ require.NotEmpty(t, testKMS)
+
+ packer := New(&provider{
+ storeProvider: mockStorage.NewCustomMockStoreProvider(store),
+ kms: testKMS,
+ })
+ require.NotEmpty(t, packer)
+
+ require.Equal(t, encodingType, packer.EncodingType())
+}
+
+func TestEncrypt(t *testing.T) {
+ testingKMS, _ := newKMS(t)
+
+ t.Run("Failure: pack without any recipients", func(t *testing.T) {
+ packer := newWithKMSAndCrypto(t, testingKMS)
+ require.NotEmpty(t, packer)
+
+ _, err := packer.Pack("", []byte("Test Message"), []byte{}, [][]byte{})
+ require.EqualError(t, err, "empty recipients keys, must have at least one recipient")
+ })
+
+ t.Run("Failure: pack with an invalid recipient key", func(t *testing.T) {
+ packer := newWithKMSAndCrypto(t, testingKMS)
+ require.NotEmpty(t, packer)
+
+ badKey := "6ZAQ7QpmR9EqhJdwx1jQsjq6nnpehwVqUbhVxiEiYEV7"
+
+ _, err := packer.Pack("", []byte("Test Message"), []byte{}, [][]byte{base58.Decode(badKey)})
+ require.EqualError(t, err, "pack: failed to build recipients: recipients keys are empty")
+ })
+
+ recipientKey := createKey(t, testingKMS)
+
+ t.Run("Success: given keys, generate envelope", func(t *testing.T) {
+ packer := newWithKMSAndCrypto(t, testingKMS)
+ require.NotEmpty(t, packer)
+
+ enc, e := packer.Pack("", []byte("Pack my box with five dozen liquor jugs!"),
+ []byte{}, [][]byte{recipientKey})
+ require.NoError(t, e)
+ require.NotEmpty(t, enc)
+ })
+
+ t.Run("Success: with multiple recipients", func(t *testing.T) {
+ rec1Key := createKey(t, testingKMS)
+ rec2Key := createKey(t, testingKMS)
+ rec3Key := createKey(t, testingKMS)
+ rec4Key := createKey(t, testingKMS)
+
+ recipientKeys := [][]byte{rec1Key, rec2Key, rec3Key, rec4Key}
+ packer := newWithKMSAndCrypto(t, testingKMS)
+ require.NotEmpty(t, packer)
+
+ enc, err := packer.Pack("", []byte("God! a red nugget! A fat egg under a dog!"), []byte{}, recipientKeys)
+ require.NoError(t, err)
+ require.NotEmpty(t, enc)
+ })
+
+ t.Run("Success: pack empty payload using deterministic random source, verify result", func(t *testing.T) {
+ senderPub := "4SPtrDH1ZH8Zsh6upbUG3TbgXjYbW1CEBRnNY6iMudX9"
+ senderPriv := "5MF9crszXCvzh9tWUWQwAuydh6tY2J5ErsaebwRzTsbNXx74mfaJXaKq7oTkoN4VMc2RtKktjMpPoU7vti9UnrdZ"
+
+ recipientPub := "CP1eVoFxCguQe1ttDbS3L35ZiJckZ8PZykX1SCDNgEYZ"
+ recipientPriv := "5aFcdEMws6ZUL7tWYrJ6DsZvY2GHZYui1jLcYquGr8uHfmyHCs96QU3nRUarH1gVYnMU2i4uUPV5STh2mX7EHpNu"
+
+ kms2, _ := newKMS(t)
+ require.NoError(t, persistKey(t, senderPub, senderPriv, kms2))
+ require.NoError(t, persistKey(t, recipientPub, recipientPriv, kms2))
+
+ source := insecurerand.NewSource(5937493) // constant fixed to ensure constant output
+ constRand := insecurerand.New(source) //nolint:gosec
+
+ packer := newWithKMSAndCrypto(t, kms2)
+ require.NotEmpty(t, packer)
+ packer.randSource = constRand
+ enc, err := packer.Pack("", nil, []byte{}, [][]byte{base58.Decode(recipientPub)})
+ require.NoError(t, err)
+
+ test := "eyJwcm90ZWN0ZWQiOiJleUpsYm1NaU9pSmphR0ZqYUdFeU1IQnZiSGt4TXpBMVgybGxkR1lpTENKMGVYQWlPaUpLVjAwdk1TNHdJaXdpWVd4bklqb2lRVzV2Ym1OeWVYQjBJaXdpY21WamFYQnBaVzUwY3lJNlczc2laVzVqY25sd2RHVmtYMnRsZVNJNklsWXRUMXBaUXpjdFNucEpVVFZGYUhCYWVIb3dTV0ZDTXkxWlZFNXhUbkZ5Y0RaRmVFVXRlbDlNUjFaaldVOVRPRkpaVkZGYVYwcHllVXRRUkU5bU5FNWtTRTVRV0VsQ1JXMUxVbEZoVURscGVGcGlNbUp0VUdnemJuZHlTR0l6VkZFelNWbExZbnBvT0ROdlBTSXNJbWhsWVdSbGNpSTZleUpyYVdRaU9pSkRVREZsVm05R2VFTm5kVkZsTVhSMFJHSlRNMHd6TlZwcFNtTnJXamhRV25scldERlRRMFJPWjBWWldpSjlmVjE5IiwiaXYiOiJpS2RxcUVqc05LaXluLWhrIiwidGFnIjoiR3FVZHVhamVfSHNLS3c3QXJ3dnQ0Zz09In0=" // nolint: lll
+
+ require.Equal(t, test, base64.URLEncoding.EncodeToString(enc))
+ })
+
+ t.Run("Success: pack payload using deterministic random source for multiple recipients, verify result", func(t *testing.T) { // nolint: lll
+ senderPub := "9NKZ9pHL9YVS7BzqJsz3e9uVvk44rJodKfLKbq4hmeUw"
+ senderPriv := "2VZLugb22G3iovUvGrecKj3VHFUNeCetkApeB4Fn4zkgBqYaMSFTW2nvF395voJ76vHkfnUXH2qvJoJnFydRoQBR"
+ senderKMS, _ := newKMS(t)
+ require.NoError(t, persistKey(t, senderPub, senderPriv, senderKMS))
+
+ rec1Pub := base58.Decode("DDk4ac2ZA19P8qXjk8XaCY9Fx7WwAmCtELkxeDNqS6Vs")
+ rec2Pub := base58.Decode("G79vtfWgtBG5J7R2QaBQpZfPUQaAab1QJWedWH7q3VK1")
+ rec3Pub := base58.Decode("7snUUwA23DVBmafz9ibmBgwFFCUwzgTzmvcJGepuzjmK")
+ rec4Pub := base58.Decode("GSRovbnQy8HRjVjvzGbbfN387EX9NFfLj89C1ScXYfrF")
+
+ source := insecurerand.NewSource(6572692) // constant fixed to ensure constant output
+ constRand := insecurerand.New(source) //nolint:gosec
+
+ packer := newWithKMSAndCrypto(t, senderKMS)
+ require.NotEmpty(t, packer)
+ packer.randSource = constRand
+ enc, err := packer.Pack(
+ "",
+ []byte("Sphinx of black quartz, judge my vow!"),
+ []byte{},
+ [][]byte{rec1Pub, rec2Pub, rec3Pub, rec4Pub})
+ require.NoError(t, err)
+
+ test := "eyJwcm90ZWN0ZWQiOiJleUpsYm1NaU9pSmphR0ZqYUdFeU1IQnZiSGt4TXpBMVgybGxkR1lpTENKMGVYQWlPaUpLVjAwdk1TNHdJaXdpWVd4bklqb2lRVzV2Ym1OeWVYQjBJaXdpY21WamFYQnBaVzUwY3lJNlczc2laVzVqY25sd2RHVmtYMnRsZVNJNklubFdTWEJ0VTFaSWEyVm9hVXRRWm1GQmRVNW1OMUpyT1c5cmJqTk9WMHhCWjBRM1NVTkNVVVpZVkVnMmN6WXRUbFpRWWtwRE1GQk9OR1ozTkZkZmVWSXpPVVpJTlU1QlJVNW9OMlpOWTBacFdYSmZNbGhCZVhwb1FubG1lRkZ6ZUhCSVh6ZEtkR00yTlVoblBTSXNJbWhsWVdSbGNpSTZleUpyYVdRaU9pSkVSR3MwWVdNeVdrRXhPVkE0Y1ZocWF6aFlZVU5aT1VaNE4xZDNRVzFEZEVWTWEzaGxSRTV4VXpaV2N5SjlmU3g3SW1WdVkzSjVjSFJsWkY5clpYa2lPaUpuZW5ScFpHeFpjWGwwUlRSb2RHczFSbTR3V21KSlRFUnJZbFZZV210WVJqTkZOUzFMTkY5dk1sWlNhREZUZUhkb2JEZHNNbWxTU20xVE1ISmlNREpxWTBaU2QwUkNkMmxxUzFWS1JYbDFTek0yYTBneldXTnRRbVl5UzFGdFVXbE1lR05KUlRoRGEzVkdRVDBpTENKb1pXRmtaWElpT25zaWEybGtJam9pUnpjNWRuUm1WMmQwUWtjMVNqZFNNbEZoUWxGd1dtWlFWVkZoUVdGaU1WRktWMlZrVjBnM2NUTldTekVpZlgwc2V5SmxibU55ZVhCMFpXUmZhMlY1SWpvaVdFdEZWMkZ3YUVzelFTMXBiRVZLTFVwNlVtdFhaRTAwZUVKcFRtTXRXa1ZvVlZwNmRVdFZSVlI2WDFSWlJqRXdSWFZNUXpoZmNHUlVUMUV6VlROSmExVmhMV0ZGUkhGalluZFpSM05VVEVkQlVWVXdZVWh4YlhWbVNHUXRUamxRVTJaVVFuVklWRTVuTFRROUlpd2lhR1ZoWkdWeUlqcDdJbXRwWkNJNklqZHpibFZWZDBFeU0wUldRbTFoWm5vNWFXSnRRbWQzUmtaRFZYZDZaMVI2YlhaalNrZGxjSFY2YW0xTEluMTlMSHNpWlc1amNubHdkR1ZrWDJ0bGVTSTZJblZwTFhFMGJtRmtRVzF5VDFSZmVteE5OWFZHWWpCT1kzRTBaV3h5YVhkQ1gwUk5kRmhsV0U5cGVIazFRblZoYW01S2RHdzVja2RvZDJONlltWmZjbEZ0WTJadUxVMUhXR3BFYlROb1NYUkVjWGQ0YmpoWmVEWnROVUU1T1V4NVdtcHBaemhVTW1OeFoycHJQU0lzSW1obFlXUmxjaUk2ZXlKcmFXUWlPaUpIVTFKdmRtSnVVWGs0U0ZKcVZtcDJla2RpWW1aT016ZzNSVmc1VGtabVRHbzRPVU14VTJOWVdXWnlSaUo5ZlYxOSIsIml2IjoiWW91Q1YtZ2xmUWhQYWw3NSIsImNpcGhlcnRleHQiOiJfY0VDazA0N2NsOGN3RWlLNVJ2S2x2TkQyY05aNW02QU1vb3ZSODJwaTBIS28xZ2ZWQT09IiwidGFnIjoiNmpZR2xreEdaRXp0ME5yQ1lkcFVLUT09In0=" // nolint: lll
+
+ require.Equal(t, test, base64.URLEncoding.EncodeToString(enc))
+ })
+}
+
+func TestEncryptComponents(t *testing.T) {
+ senderPub := "9NKZ9pHL9YVS7BzqJsz3e9uVvk44rJodKfLKbq4hmeUw"
+ senderPriv := "2VZLugb22G3iovUvGrecKj3VHFUNeCetkApeB4Fn4zkgBqYaMSFTW2nvF395voJ76vHkfnUXH2qvJoJnFydRoQBR"
+ recPub := "DDk4ac2ZA19P8qXjk8XaCY9Fx7WwAmCtELkxeDNqS6Vs"
+
+ testKMS, _ := newKMS(t)
+ require.NoError(t, persistKey(t, senderPub, senderPriv, testKMS))
+
+ packer := newWithKMSAndCrypto(t, testKMS)
+
+ t.Run("Failure: content encryption nonce generation fails", func(t *testing.T) {
+ failRand := newFailReader(0, rand.Reader)
+ packer.randSource = failRand
+
+ _, err := packer.Pack(
+ "",
+ []byte("Lorem Ipsum Dolor Sit Amet Consectetur Adispici Elit"),
+ []byte{}, [][]byte{base58.Decode(recPub)})
+ require.EqualError(t, err, "pack: failed to generate random nonce: mock Reader has failed intentionally")
+ })
+
+ t.Run("Failure: CEK generation fails", func(t *testing.T) {
+ failRand := newFailReader(1, rand.Reader)
+ packer.randSource = failRand
+
+ _, err := packer.Pack(
+ "",
+ []byte("Lorem Ipsum Dolor Sit Amet Consectetur Adispici Elit"),
+ []byte{}, [][]byte{base58.Decode(recPub)})
+ require.EqualError(t, err, "pack: failed to generate cek: mock Reader has failed intentionally")
+ })
+
+ t.Run("Failure: recipient nonce generation fails", func(t *testing.T) {
+ failRand := newFailReader(2, rand.Reader)
+ packer.randSource = failRand
+
+ _, err := packer.Pack(
+ "", []byte(
+ "Lorem Ipsum Dolor Sit Amet Consectetur Adispici Elit"),
+ []byte{}, [][]byte{base58.Decode(recPub)})
+ require.EqualError(t, err, "pack: failed to build recipients: recipients keys are empty")
+ })
+
+ t.Run("Success: 3 reads necessary for pack", func(t *testing.T) {
+ failRand := newFailReader(3, rand.Reader)
+ packer.randSource = failRand
+
+ _, err := packer.Pack(
+ "",
+ []byte("Lorem Ipsum Dolor Sit Amet Consectetur Adispici Elit"),
+ []byte{}, [][]byte{base58.Decode(recPub)})
+ require.NoError(t, err)
+ })
+}
+
+func TestDecrypt(t *testing.T) {
+ testingKMS, _ := newKMS(t)
+
+ _, recKey, err := testingKMS.CreateAndExportPubKeyBytes(kms.ED25519Type)
+ require.NoError(t, err)
+
+ t.Run("Success: pack then unpack, same packer", func(t *testing.T) {
+ packer := newWithKMSAndCrypto(t, testingKMS)
+ msgIn := []byte("Junky qoph-flags vext crwd zimb.")
+
+ var (
+ enc []byte
+ env *transport.Envelope
+ )
+
+ enc, err = packer.Pack("", msgIn, []byte{}, [][]byte{recKey})
+ require.NoError(t, err)
+ env, err = packer.Unpack(enc)
+ require.NoError(t, err)
+
+ require.ElementsMatch(t, msgIn, env.Message)
+ require.Equal(t, recKey, env.ToKey)
+ })
+
+ t.Run("Success: pack and unpack, different packers, including fail recipient who wasn't sent the message", func(t *testing.T) { // nolint: lll
+ rec1KMS, _ := newKMS(t)
+ rec1Key := createKey(t, rec1KMS)
+
+ rec2KMS, _ := newKMS(t)
+ rec2Key := createKey(t, rec2KMS)
+
+ rec3KMS, _ := newKMS(t)
+ rec3Key := createKey(t, rec3KMS)
+
+ require.NoError(t, err)
+
+ sendPacker := newWithKMSAndCrypto(t, testingKMS)
+ rec2Packer := newWithKMSAndCrypto(t, rec2KMS)
+
+ msgIn := []byte("Junky qoph-flags vext crwd zimb.")
+
+ var (
+ enc []byte
+ env *transport.Envelope
+ )
+
+ enc, err = sendPacker.Pack("", msgIn, []byte{}, [][]byte{rec1Key, rec2Key, rec3Key})
+ require.NoError(t, err)
+ env, err = rec2Packer.Unpack(enc)
+ require.NoError(t, err)
+ require.ElementsMatch(t, msgIn, env.Message)
+ require.Equal(t, rec2Key, env.ToKey)
+
+ emptyKMS, _ := newKMS(t)
+ rec4Packer := newWithKMSAndCrypto(t, emptyKMS)
+
+ _, err = rec4Packer.Unpack(enc)
+ require.NotNil(t, err)
+ require.Contains(t, err.Error(), "no key accessible")
+ })
+
+ t.Run("Test unpacking envelope", func(t *testing.T) {
+ env := `{"protected":"eyJlbmMiOiJjaGFjaGEyMHBvbHkxMzA1X2lldGYiLCJ0eXAiOiJKV00vMS4wIiwiYWxnIjoiQW5vbmNyeXB0IiwicmVjaXBpZW50cyI6W3siZW5jcnlwdGVkX2tleSI6IjN3eFg1UUYybmVuYzUwUlRmSG10TmpQcVdieVhsOURseXhvRHlOYWx2a3U4MUhQdDVGanNrS3JpR1A1dE9FaHhYNmNyT3E2bjcxZXJRMU5zdWhGcm43VXVTUll3anRucmt1bmFaMjNaOWxZPSIsImhlYWRlciI6eyJraWQiOiI0U1B0ckRIMVpIOFpzaDZ1cGJVRzNUYmdYalliVzFDRUJSbk5ZNmlNdWRYOSJ9fV19","iv":"_Bp1NvfmNZ5Qe3iH","ciphertext":"eyETwK9I4NNPyitd","tag":"M8tMmORU7k11SvB_vStMpA=="}` // nolint: lll
+ msg := "Hello World!"
+
+ recPub := "4SPtrDH1ZH8Zsh6upbUG3TbgXjYbW1CEBRnNY6iMudX9"
+ recPriv := "5MF9crszXCvzh9tWUWQwAuydh6tY2J5ErsaebwRzTsbNXx74mfaJXaKq7oTkoN4VMc2RtKktjMpPoU7vti9UnrdZ"
+
+ recKMS, _ := newKMS(t)
+ require.NoError(t, persistKey(t, recPub, recPriv, recKMS))
+
+ recPacker := newWithKMSAndCrypto(t, recKMS)
+
+ var envOut *transport.Envelope
+ envOut, err = recPacker.Unpack([]byte(env))
+ require.NoError(t, err)
+ require.ElementsMatch(t, []byte(msg), envOut.Message)
+ require.Empty(t, envOut.FromKey)
+ require.NotEmpty(t, envOut.ToKey)
+ require.Equal(t, recPub, base58.Encode(envOut.ToKey))
+ })
+
+ t.Run("Test unpacking envelope with multiple recipients", func(t *testing.T) {
+ env := `{"protected":"eyJlbmMiOiJjaGFjaGEyMHBvbHkxMzA1X2lldGYiLCJ0eXAiOiJKV00vMS4wIiwiYWxnIjoiQW5vbmNyeXB0IiwicmVjaXBpZW50cyI6W3siZW5jcnlwdGVkX2tleSI6ImZDMzgxN05OUWVCSTBtODNGOVlwbXdCWE5VNlRkX2V5WWdfSHI1WW41Z1ZlclliZmlHUXFTdGlZVmRBSUc4RlgwclJKd1c3SVBtYUcyTDY3dmQwSXZwWFowQ2sydjlfSldDbjNjSWkwa3Y0PSIsImhlYWRlciI6eyJraWQiOiJGN21OdEYyZnJMdVJ1MmNNRWpYQm5XZFljVFpBWE5QOWpFa3ByWHhpYVppMSJ9fSx7ImVuY3J5cHRlZF9rZXkiOiJKTjdaN3ZhOHc0T05iQkVnczI1bTdYbVFRM2NqTGo0WkZrRzBSOVc5SndVX1RsV3g5Q1pvb3lrZDZ4SWZBZk1tNVJjTjZIaGZKdEg5enpiVlVuVTlObF8wck9MVm96WEVIUGF1R2Vkc25uOD0iLCJoZWFkZXIiOnsia2lkIjoiQVE5bkh0TG5tdUc4MXB5NjRZRzVnZUYydmQ1aFFDS0hpNU1ycVExTFlDWEUifX1dfQ==","iv":"s5LdqRVlm23pxhxq","ciphertext":"HiMHFMlk6nwg7F6Q","tag":"tqPiHBpA2h4TeZFB9wNnyw=="}` // nolint: lll
+ msg := "Hello World!"
+
+ rec1Pub := "F7mNtF2frLuRu2cMEjXBnWdYcTZAXNP9jEkprXxiaZi1"
+ rec1Priv := "2nYsWTQ1ZguQ7G2HYfMWjMNqWagBQfaKB9GLbsFk7Z7tKVBEr2arwpVKDwgLUbaxguUzQuf7o67aWKzgtHmKaypM"
+
+ rec2Pub := "AQ9nHtLnmuG81py64YG5geF2vd5hQCKHi5MrqQ1LYCXE"
+ rec2Priv := "2YbSVZzSVaim41bWDdsBzamrhXrPFKKEpzXZRmgDuoFJco5VQELRSj1oWFR9aRdaufsdUyw8sozTtZuX8Mzsqboz"
+
+ rec1KMS, _ := newKMS(t)
+ require.NoError(t, persistKey(t, rec1Pub, rec1Priv, rec1KMS))
+
+ rec2KMS, _ := newKMS(t)
+ require.NoError(t, persistKey(t, rec2Pub, rec2Priv, rec2KMS))
+
+ rec1Packer := newWithKMSAndCrypto(t, rec1KMS)
+ rec2Packer := newWithKMSAndCrypto(t, rec2KMS)
+
+ var envOut *transport.Envelope
+ envOut, err = rec1Packer.Unpack([]byte(env))
+ require.NoError(t, err)
+ require.ElementsMatch(t, []byte(msg), envOut.Message)
+ require.Empty(t, envOut.FromKey)
+ require.NotEmpty(t, envOut.ToKey)
+ require.Equal(t, rec1Pub, base58.Encode(envOut.ToKey))
+
+ envOut, err = rec2Packer.Unpack([]byte(env))
+ require.NoError(t, err)
+ require.ElementsMatch(t, []byte(msg), envOut.Message)
+ require.Empty(t, envOut.FromKey)
+ require.NotEmpty(t, envOut.ToKey)
+ require.Equal(t, rec2Pub, base58.Encode(envOut.ToKey))
+ })
+
+ t.Run("Test unpacking envelope with invalid recipient", func(t *testing.T) {
+ env := `{"protected":"eyJlbmMiOiJjaGFjaGEyMHBvbHkxMzA1X2lldGYiLCJ0eXAiOiJKV00vMS4wIiwiYWxnIjoiQW5vbmNyeXB0IiwicmVjaXBpZW50cyI6W3siZW5jcnlwdGVkX2tleSI6IkgwY09vVk5pT3FybTZPUFR1YzJ4cnBYaTRrTm1kSnhZV3haOE1iRWVOU0pYMENkR3EzaWRpQmtibjVYSDBTWjBtNEpfa0NYUFJaYVNqYjhLMVB3X0s5NnYzTFBjVzVPWjhWVkNKYkhHRUU0PSIsImhlYWRlciI6eyJraWQiOiJGN21OdEYyZnJMdVJ1MmNNRWpYQm5XZFljVFpBWE5QOWpFa3ByWHhpYVppMSJ9fV19","iv":"6cVlG23Fhy9oXB2h","ciphertext":"8vMl1QjgbCHreGCe","tag":"-VYChuk4kmnTk8Kz0Kz3Pg=="}` // nolint: lll
+
+ recPub := "A3KnccxQu27yWQrSLwA2YFbfoSs4CHo3q6LjvhmpKz9h"
+ recPriv := "49Y63zwonNoj2jEhMYE22TDwQCn7RLKMqNeSkSoBBucbAWceJuXXNCACXfpbXD7PHKM13SWaySyDukEakPVn5sWs"
+
+ recKMS, _ := newKMS(t)
+ require.NoError(t, persistKey(t, recPub, recPriv, recKMS))
+
+ recPacker := newWithKMSAndCrypto(t, recKMS)
+
+ _, err = recPacker.Unpack([]byte(env))
+ require.NotNil(t, err)
+ require.Contains(t, err.Error(), "no key accessible")
+ })
+}
+
+func unpackComponentFailureTest(t *testing.T, protectedHeader, msg, recKeyPub, recKeyPriv, errString string) {
+ t.Helper()
+
+ fullMessage := `{"protected": "` + base64.URLEncoding.EncodeToString([]byte(protectedHeader)) + "\", " + msg
+
+ w, _ := newKMS(t)
+
+ err := persistKey(t, recKeyPub, recKeyPriv, w)
+
+ if errString == "createKID: empty key" {
+ require.EqualError(t, err, errString)
+ return
+ }
+
+ require.NoError(t, err)
+
+ recPacker := newWithKMSAndCrypto(t, w)
+ _, err = recPacker.Unpack([]byte(fullMessage))
+ require.NotNil(t, err)
+ require.Contains(t, err.Error(), errString)
+}
+
+func TestUnpackComponents(t *testing.T) {
+ recKeyPub := "F7mNtF2frLuRu2cMEjXBnWdYcTZAXNP9jEkprXxiaZi1"
+ recKeyPriv := "2nYsWTQ1ZguQ7G2HYfMWjMNqWagBQfaKB9GLbsFk7Z7tKVBEr2arwpVKDwgLUbaxguUzQuf7o67aWKzgtHmKaypM"
+
+ t.Run("Fail: non-JSON envelope", func(t *testing.T) {
+ msg := `ed": "eyJlbmMiOiAieGNoYWNoYTIwcG9seTEzMDVfaWV0ZiIsICJ0eXAiOiAiSldNLzEu"}`
+
+ w, _ := newKMS(t)
+ require.NoError(t, persistKey(t, recKeyPub, recKeyPriv, w))
+
+ recPacker := newWithKMSAndCrypto(t, w)
+
+ _, err := recPacker.Unpack([]byte(msg))
+ require.EqualError(t, err, "invalid character 'e' looking for beginning of value")
+ })
+
+ t.Run("Fail: non-base64 protected header", func(t *testing.T) {
+ msg := `{"protected":"&**^(&^%","iv":"6cVlG23Fhy9oXB2h","ciphertext":"8vMl1QjgbCHreGCe","tag":"-VYChuk4kmnTk8Kz0Kz3Pg=="}` // nolint: lll
+
+ w, _ := newKMS(t)
+ require.NoError(t, persistKey(t, recKeyPub, recKeyPriv, w))
+
+ recPacker := newWithKMSAndCrypto(t, w)
+
+ _, err := recPacker.Unpack([]byte(msg))
+ require.EqualError(t, err, "illegal base64 data at input byte 0")
+ })
+
+ t.Run("Fail: header not json", func(t *testing.T) {
+ unpackComponentFailureTest(t,
+ `}eyJlbmMiOiAieGNoYWNoYTIwcG9seTEzMDVfaWV0ZiIsICJ0eXAiOiAiSldNLzEuMC`,
+ `"not important":[]}`,
+ recKeyPub, recKeyPriv,
+ "invalid character '}' looking for beginning of value")
+ })
+
+ t.Run("Fail: bad 'typ' field", func(t *testing.T) {
+ unpackComponentFailureTest(t,
+ `{"enc":"chacha20poly1305_ietf","typ":"JSON","alg":"Anoncrypt","recipients":[{"encrypted_key":"H0cOoVNiOqrm6OPTuc2xrpXi4kNmdJxYWxZ8MbEeNSJX0CdGq3idiBkbn5XH0SZ0m4J_kCXPRZaSjb8K1Pw_K96v3LPcW5OZ8VVCJbHGEE4=","header":{"kid":"F7mNtF2frLuRu2cMEjXBnWdYcTZAXNP9jEkprXxiaZi1"}}]}`, // nolint: lll
+ `"iv": "oDZpVO648Po3UcoW", "ciphertext": "pLrFQ6dND0aB4saHjSklcNTDAvpFPmIvebCis7S6UupzhhPOHwhp6o97_EphsWbwqqHl0HTiT7W9kUqrvd8jcWgx5EATtkx5o3PSyHfsfm9jl0tmKsqu6VG0RML_OokZiFv76ZUZuGMrHKxkCHGytILhlpSwajg=", "tag": "6GigdWnW59aC9Y8jhy76rA=="}`, // nolint: lll
+ recKeyPub, recKeyPriv,
+ "message type JSON not supported")
+ })
+
+ t.Run("Fail: authcrypt not supported", func(t *testing.T) {
+ unpackComponentFailureTest(t,
+ `{"enc":"chacha20poly1305_ietf","typ":"JWM/1.0","alg":"Authcrypt","recipients":[{"encrypted_key":"H0cOoVNiOqrm6OPTuc2xrpXi4kNmdJxYWxZ8MbEeNSJX0CdGq3idiBkbn5XH0SZ0m4J_kCXPRZaSjb8K1Pw_K96v3LPcW5OZ8VVCJbHGEE4=","header":{"kid":"F7mNtF2frLuRu2cMEjXBnWdYcTZAXNP9jEkprXxiaZi1"}}]}`, // nolint: lll
+ `"iv": "oDZpVO648Po3UcoW", "ciphertext": "pLrFQ6dND0aB4saHjSklcNTDAvpFPmIvebCis7S6UupzhhPOHwhp6o97_EphsWbwqqHl0HTiT7W9kUqrvd8jcWgx5EATtkx5o3PSyHfsfm9jl0tmKsqu6VG0RML_OokZiFv76ZUZuGMrHKxkCHGytILhlpSwajg=", "tag": "6GigdWnW59aC9Y8jhy76rA=="}`, // nolint: lll
+ recKeyPub, recKeyPriv,
+ "message format Authcrypt not supported")
+ })
+
+ t.Run("Fail: no recipients in header", func(t *testing.T) {
+ unpackComponentFailureTest(t,
+ `{"enc": "xchacha20poly1305_ietf", "typ": "JWM/1.0", "alg": "Anoncrypt", "recipients": []}`,
+ `"iv": "oDZpVO648Po3UcoW", "ciphertext": "pLrFQ6dND0aB4saHjSklcNTDAvpFPmIvebCis7S6UupzhhPOHwhp6o97_EphsWbwqqHl0HTiT7W9kUqrvd8jcWgx5EATtkx5o3PSyHfsfm9jl0tmKsqu6VG0RML_OokZiFv76ZUZuGMrHKxkCHGytILhlpSwajg=", "tag": "6GigdWnW59aC9Y8jhy76rA=="}`, // nolint: lll
+ recKeyPub, recKeyPriv,
+ "no key accessible")
+ })
+
+ t.Run("Fail: invalid public key", func(t *testing.T) {
+ recPub := "6ZAQ7QpmR9EqhJdwx1jQsjq6nnpehwVqUbhVxiEiYEV7" // invalid key, won't convert
+
+ unpackComponentFailureTest(t,
+ `{"enc":"chacha20poly1305_ietf","typ":"JWM/1.0","alg":"Anoncrypt","recipients":[{"encrypted_key":"H0cOoVNiOqrm6OPTuc2xrpXi4kNmdJxYWxZ8MbEeNSJX0CdGq3idiBkbn5XH0SZ0m4J_kCXPRZaSjb8K1Pw_K96v3LPcW5OZ8VVCJbHGEE4=","header":{"kid":"6ZAQ7QpmR9EqhJdwx1jQsjq6nnpehwVqUbhVxiEiYEV7"}}]}`, // nolint: lll
+ `"iv": "oDZpVO648Po3UcoW", "ciphertext": "pLrFQ6dND0aB4saHjSklcNTDAvpFPmIvebCis7S6UupzhhPOHwhp6o97_EphsWbwqqHl0HTiT7W9kUqrvd8jcWgx5EATtkx5o3PSyHfsfm9jl0tmKsqu6VG0RML_OokZiFv76ZUZuGMrHKxkCHGytILhlpSwajg=", "tag": "6GigdWnW59aC9Y8jhy76rA=="}`, // nolint: lll
+ recPub, recKeyPriv,
+ "sealOpen: failed to convert pub Ed25519 to X25519 key: error converting public key")
+ })
+
+ t.Run("Fail: invalid public key", func(t *testing.T) {
+ recPub := "57N4aoQKaxUGNeEn3ETnTKgeD1L5Wm3U3Vb8qi3hupLn" // mismatched keypair, won't decrypt
+
+ unpackComponentFailureTest(t,
+ `{"enc":"chacha20poly1305_ietf","typ":"JWM/1.0","alg":"Anoncrypt","recipients":[{"encrypted_key":"H0cOoVNiOqrm6OPTuc2xrpXi4kNmdJxYWxZ8MbEeNSJX0CdGq3idiBkbn5XH0SZ0m4J_kCXPRZaSjb8K1Pw_K96v3LPcW5OZ8VVCJbHGEE4=","header":{"kid":"57N4aoQKaxUGNeEn3ETnTKgeD1L5Wm3U3Vb8qi3hupLn"}}]}`, // nolint: lll
+ `"iv": "oDZpVO648Po3UcoW", "ciphertext": "pLrFQ6dND0aB4saHjSklcNTDAvpFPmIvebCis7S6UupzhhPOHwhp6o97_EphsWbwqqHl0HTiT7W9kUqrvd8jcWgx5EATtkx5o3PSyHfsfm9jl0tmKsqu6VG0RML_OokZiFv76ZUZuGMrHKxkCHGytILhlpSwajg=", "tag": "6GigdWnW59aC9Y8jhy76rA=="}`, // nolint: lll
+ recPub, recKeyPriv,
+ "failed to unpack")
+ })
+
+ t.Run("Encrypted CEK is invalid base64 data", func(t *testing.T) {
+ unpackComponentFailureTest(t,
+ `{"enc":"chacha20poly1305_ietf","typ":"JWM/1.0","alg":"Anoncrypt","recipients":[{"encrypted_key":"-","header":{"kid":"F7mNtF2frLuRu2cMEjXBnWdYcTZAXNP9jEkprXxiaZi1"}}]}`, // nolint: lll
+ `"iv": "oDZpVO648Po3UcoW", "ciphertext": "pLrFQ6dND0aB4saHjSklcNTDAvpFPmIvebCis7S6UupzhhPOHwhp6o97_EphsWbwqqHl0HTiT7W9kUqrvd8jcWgx5EATtkx5o3PSyHfsfm9jl0tmKsqu6VG0RML_OokZiFv76ZUZuGMrHKxkCHGytILhlpSwajg=", "tag": "6GigdWnW59aC9Y8jhy76rA=="}`, // nolint: lll
+ recKeyPub, recKeyPriv,
+ "illegal base64 data at input byte 0")
+ })
+
+ t.Run("Bad encrypted key cannot be decrypted", func(t *testing.T) {
+ unpackComponentFailureTest(t,
+ `{"enc":"chacha20poly1305_ietf","typ":"JWM/1.0","alg":"Anoncrypt","recipients":[{"encrypted_key":"H0cOoVNi","header":{"kid":"F7mNtF2frLuRu2cMEjXBnWdYcTZAXNP9jEkprXxiaZi1"}}]}`, // nolint: lll
+ `"iv": "oDZpVO648Po3UcoW", "ciphertext": "pLrFQ6dND0aB4saHjSklcNTDAvpFPmIvebCis7S6UupzhhPOHwhp6o97_EphsWbwqqHl0HTiT7W9kUqrvd8jcWgx5EATtkx5o3PSyHfsfm9jl0tmKsqu6VG0RML_OokZiFv76ZUZuGMrHKxkCHGytILhlpSwajg=", "tag": "6GigdWnW59aC9Y8jhy76rA=="}`, // nolint: lll
+ recKeyPub, recKeyPriv,
+ "failed to decrypt CEK")
+ })
+
+ // valid protected header for envelope being used
+ prot := `{"enc":"chacha20poly1305_ietf","typ":"JWM/1.0","alg":"Anoncrypt","recipients":[{"encrypted_key":"H0cOoVNiOqrm6OPTuc2xrpXi4kNmdJxYWxZ8MbEeNSJX0CdGq3idiBkbn5XH0SZ0m4J_kCXPRZaSjb8K1Pw_K96v3LPcW5OZ8VVCJbHGEE4=","header":{"kid":"F7mNtF2frLuRu2cMEjXBnWdYcTZAXNP9jEkprXxiaZi1"}}]}` // nolint: lll
+
+ t.Run("Ciphertext nonce not valid b64 data", func(t *testing.T) {
+ unpackComponentFailureTest(t,
+ prot,
+ `"iv":"!!!","ciphertext":"8vMl1QjgbCHreGCe","tag":"-VYChuk4kmnTk8Kz0Kz3Pg=="}`,
+ recKeyPub, recKeyPriv,
+ "illegal base64 data at input byte 0")
+ })
+
+ t.Run("Ciphertext not valid b64 data", func(t *testing.T) {
+ unpackComponentFailureTest(t,
+ prot, `"iv":"6cVlG23Fhy9oXB2h","ciphertext":"-","tag":"-VYChuk4kmnTk8Kz0Kz3Pg=="}`,
+ recKeyPub, recKeyPriv,
+ "illegal base64 data at input byte 0")
+ })
+
+ t.Run("Ciphertext tag not valid b64 data", func(t *testing.T) {
+ unpackComponentFailureTest(t,
+ prot,
+ `"iv":"6cVlG23Fhy9oXB2h","ciphertext":"8vMl1QjgbCHreGCe","tag":"-"}`,
+ recKeyPub, recKeyPriv,
+ "illegal base64 data at input byte 0")
+ })
+
+ badKeyPriv := "badkeyabcdefghijklmnopqrstuvwxyzbadkeyabcdefghijklmnopqrstuvwxyz"
+ badKeyPub := "badkeyabcdefghijklmnopqrstuvwxyz"
+
+ t.Run("Recipient Key not valid key", func(t *testing.T) {
+ unpackComponentFailureTest(t,
+ prot,
+ `"iv":"6cVlG23Fhy9oXB2h","ciphertext":"8vMl1QjgbCHreGCe","tag":"-VYChuk4kmnTk8Kz0Kz3Pg=="}`,
+ badKeyPub, badKeyPriv,
+ "createKID: empty key")
+ })
+}
+
+func Test_getCEK(t *testing.T) {
+ k := mockkms.KeyManager{
+ GetKeyValue: nil,
+ GetKeyErr: fmt.Errorf("mock error"),
+ }
+
+ recs := []recipient{
+ {
+ EncryptedKey: "",
+ Header: recipientHeader{
+ KID: "BADKEY",
+ },
+ },
+ }
+
+ _, err := getCEK(recs, &k)
+ require.EqualError(t, err, "getCEK: no key accessible none of the recipient keys were found in kms: "+
+ "[mock error]")
+}
+
+func Test_newCryptoBox(t *testing.T) {
+ _, err := newCryptoBox(&mockkms.KeyManager{})
+ require.EqualError(t, err, "cannot use parameter argument as KMS")
+
+ _, err = newCryptoBox(&webkms.RemoteKMS{})
+ require.NoError(t, err)
+}
diff --git a/pkg/didcomm/packer/legacy/anoncrypt/pack.go b/pkg/didcomm/packer/legacy/anoncrypt/pack.go
new file mode 100644
index 000000000..b8fdedce8
--- /dev/null
+++ b/pkg/didcomm/packer/legacy/anoncrypt/pack.go
@@ -0,0 +1,148 @@
+/*
+Copyright Avast Software. All Rights Reserved.
+
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package anoncryt
+
+import (
+ "encoding/base64"
+ "encoding/json"
+ "errors"
+ "fmt"
+
+ "github.com/btcsuite/btcutil/base58"
+ chacha "golang.org/x/crypto/chacha20poly1305"
+ "golang.org/x/crypto/poly1305"
+
+ "github.com/hyperledger/aries-framework-go/pkg/common/log"
+ "github.com/hyperledger/aries-framework-go/pkg/internal/cryptoutil"
+)
+
+var logger = log.New("aries-framework/pkg/didcomm/packer/legacy/anoncrypt")
+
+// Pack will encode the payload argument
+// Using the protocol defined by Aries RFC 0019.
+func (p *Packer) Pack(_ string, payload, _ []byte, recipientPubKeys [][]byte) ([]byte, error) {
+ var err error
+
+ if len(recipientPubKeys) == 0 {
+ return nil, errors.New("empty recipients keys, must have at least one recipient")
+ }
+
+ nonce := make([]byte, chacha.NonceSize)
+
+ _, err = p.randSource.Read(nonce)
+ if err != nil {
+ return nil, fmt.Errorf("pack: failed to generate random nonce: %w", err)
+ }
+
+ // cek (content encryption key) is a symmetric key, for chacha20, a symmetric cipher
+ cek := &[chacha.KeySize]byte{}
+
+ _, err = p.randSource.Read(cek[:])
+ if err != nil {
+ return nil, fmt.Errorf("pack: failed to generate cek: %w", err)
+ }
+
+ var recipients []recipient
+
+ recipients, err = p.buildRecipients(cek, recipientPubKeys)
+ if err != nil {
+ return nil, fmt.Errorf("pack: failed to build recipients: %w", err)
+ }
+
+ header := protected{
+ Enc: anonCryptEncType,
+ Typ: encodingType,
+ Alg: anonCrypt,
+ Recipients: recipients,
+ }
+
+ return p.buildEnvelope(nonce, payload, cek[:], &header)
+}
+
+func (p *Packer) buildEnvelope(nonce, payload, cek []byte, header *protected) ([]byte, error) {
+ protectedBytes, err := json.Marshal(header)
+ if err != nil {
+ return nil, err
+ }
+
+ protectedB64 := base64.URLEncoding.EncodeToString(protectedBytes)
+
+ chachaCipher, err := chacha.New(cek)
+ if err != nil {
+ return nil, err
+ }
+
+ // Additional data is b64encode(jsonencode(header))
+ symPld := chachaCipher.Seal(nil, nonce, payload, []byte(protectedB64))
+
+ // symPld has a length of len(pld) + poly1305.TagSize
+ // fetch the tag from the tail
+ tag := symPld[len(symPld)-poly1305.TagSize:]
+ // fetch the cipherText from the head (0:up to the trailing tag)
+ cipherText := symPld[0 : len(symPld)-poly1305.TagSize]
+
+ env := legacyEnvelope{
+ Protected: protectedB64,
+ IV: base64.URLEncoding.EncodeToString(nonce),
+ CipherText: base64.URLEncoding.EncodeToString(cipherText),
+ Tag: base64.URLEncoding.EncodeToString(tag),
+ }
+
+ out, err := json.Marshal(env)
+ if err != nil {
+ return nil, err
+ }
+
+ return out, nil
+}
+
+func (p *Packer) buildRecipients(cek *[chacha.KeySize]byte, recPubKeys [][]byte) ([]recipient, error) {
+ encodedRecipients := make([]recipient, 0)
+
+ for _, recKey := range recPubKeys {
+ rec, err := p.buildRecipient(cek, recKey)
+ if err != nil {
+ logger.Warnf("buildRecipients: failed to build recipient: %w", err)
+
+ continue
+ }
+
+ encodedRecipients = append(encodedRecipients, *rec)
+ }
+
+ if len(encodedRecipients) == 0 {
+ return nil, fmt.Errorf("recipients keys are empty")
+ }
+
+ return encodedRecipients, nil
+}
+
+// buildRecipient encodes the necessary data for the recipient to decrypt the message
+// encrypting the CEK.
+func (p *Packer) buildRecipient(cek *[chacha.KeySize]byte, recKey []byte) (*recipient, error) {
+ recEncKey, err := cryptoutil.PublicEd25519toCurve25519(recKey)
+ if err != nil {
+ return nil, fmt.Errorf("buildRecipient: failed to convert public Ed25519 to Curve25519: %w", err)
+ }
+
+ box, err := newCryptoBox(p.kms)
+ if err != nil {
+ return nil, fmt.Errorf("buildRecipient: failed to create new CryptoBox: %w", err)
+ }
+
+ encCEK, err := box.Seal(cek[:], recEncKey, p.randSource)
+ if err != nil {
+ return nil, fmt.Errorf("buildRecipient: failed to encrypt cek: %w", err)
+ }
+
+ return &recipient{
+ EncryptedKey: base64.URLEncoding.EncodeToString(encCEK),
+ Header: recipientHeader{
+ KID: base58.Encode(recKey), // recKey is the Ed25519 recipient pk in b58 encoding
+ },
+ }, nil
+}
diff --git a/pkg/didcomm/packer/legacy/anoncrypt/unpack.go b/pkg/didcomm/packer/legacy/anoncrypt/unpack.go
new file mode 100644
index 000000000..243185e92
--- /dev/null
+++ b/pkg/didcomm/packer/legacy/anoncrypt/unpack.go
@@ -0,0 +1,165 @@
+/*
+Copyright Avast Software. All Rights Reserved.
+
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package anoncryt
+
+import (
+ "encoding/base64"
+ "encoding/json"
+ "fmt"
+
+ "github.com/btcsuite/btcutil/base58"
+ chacha "golang.org/x/crypto/chacha20poly1305"
+
+ "github.com/hyperledger/aries-framework-go/pkg/didcomm/transport"
+ "github.com/hyperledger/aries-framework-go/pkg/kms"
+ "github.com/hyperledger/aries-framework-go/pkg/kms/localkms"
+)
+
+// Unpack will decode the envelope using the legacy format
+// Using (X)Chacha20 encryption algorithm and Poly1035 authenticator.
+func (p *Packer) Unpack(envelope []byte) (*transport.Envelope, error) {
+ var envelopeData legacyEnvelope
+
+ err := json.Unmarshal(envelope, &envelopeData)
+ if err != nil {
+ return nil, err
+ }
+
+ protectedBytes, err := base64.URLEncoding.DecodeString(envelopeData.Protected)
+ if err != nil {
+ return nil, err
+ }
+
+ var protectedData protected
+
+ err = json.Unmarshal(protectedBytes, &protectedData)
+ if err != nil {
+ return nil, err
+ }
+
+ if protectedData.Typ != encodingType {
+ return nil, fmt.Errorf("message type %s not supported", protectedData.Typ)
+ }
+
+ if protectedData.Alg != anonCrypt {
+ return nil, fmt.Errorf("message format %s not supported", protectedData.Alg)
+ }
+
+ keys, err := getCEK(protectedData.Recipients, p.kms)
+ if err != nil {
+ return nil, err
+ }
+
+ cek, recKey := keys.cek, keys.myKey
+
+ data, err := p.decodeCipherText(cek, &envelopeData)
+
+ return &transport.Envelope{
+ Message: data,
+ ToKey: recKey,
+ }, err
+}
+
+type keys struct {
+ cek *[chacha.KeySize]byte
+ myKey []byte
+}
+
+func getCEK(recipients []recipient, km kms.KeyManager) (*keys, error) {
+ var candidateKeys []string
+
+ for _, candidate := range recipients {
+ candidateKeys = append(candidateKeys, candidate.Header.KID)
+ }
+
+ recKeyIdx, err := findVerKey(km, candidateKeys)
+ if err != nil {
+ return nil, fmt.Errorf("getCEK: no key accessible %w", err)
+ }
+
+ recip := recipients[recKeyIdx]
+ recKey := base58.Decode(recip.Header.KID)
+
+ encCEK, err := base64.URLEncoding.DecodeString(recip.EncryptedKey)
+ if err != nil {
+ return nil, err
+ }
+
+ b, err := newCryptoBox(km)
+ if err != nil {
+ return nil, err
+ }
+
+ cekSlice, err := b.SealOpen(encCEK, recKey)
+ if err != nil {
+ return nil, fmt.Errorf("failed to decrypt CEK: %w", err)
+ }
+
+ var cek [chacha.KeySize]byte
+
+ copy(cek[:], cekSlice)
+
+ return &keys{
+ cek: &cek,
+ myKey: recKey,
+ }, nil
+}
+
+func findVerKey(km kms.KeyManager, candidateKeys []string) (int, error) {
+ var errs []error
+
+ for i, key := range candidateKeys {
+ recKID, err := localkms.CreateKID(base58.Decode(key), kms.ED25519Type)
+ if err != nil {
+ return -1, err
+ }
+
+ _, err = km.Get(recKID)
+ if err == nil {
+ return i, nil
+ }
+
+ errs = append(errs, err)
+ }
+
+ return -1, fmt.Errorf("none of the recipient keys were found in kms: %v", errs)
+}
+
+// decodeCipherText decodes (from base64) and decrypts the ciphertext using chacha20poly1305.
+func (p *Packer) decodeCipherText(cek *[chacha.KeySize]byte, envelope *legacyEnvelope) ([]byte, error) {
+ var cipherText, nonce, tag, aad, message []byte
+ aad = []byte(envelope.Protected)
+
+ cipherText, err := base64.URLEncoding.DecodeString(envelope.CipherText)
+ if err != nil {
+ return nil, fmt.Errorf("decodeCipherText: failed to decode b64Sender: %w", err)
+ }
+
+ nonce, err = base64.URLEncoding.DecodeString(envelope.IV)
+ if err != nil {
+ return nil, err
+ }
+
+ tag, err = base64.URLEncoding.DecodeString(envelope.Tag)
+ if err != nil {
+ return nil, err
+ }
+
+ chachaCipher, err := chacha.New(cek[:])
+ if err != nil {
+ return nil, err
+ }
+
+ payload := append(cipherText, tag...)
+
+ message, err = chachaCipher.Open(nil, nonce, payload, aad)
+ if err != nil {
+ return nil, err
+ }
+
+ return message, nil
+}
From d5d31b7d24e76fac32aa620f94f980a7abc5fa87 Mon Sep 17 00:00:00 2001
From: Alexander Shcherbakov
Date: Wed, 13 Jul 2022 18:39:19 +0500
Subject: [PATCH 52/54] CL Anoncreds tink primitives based on ursa-wrapper-go
(#3271)
Signed-off-by: alexander.shcherbakov
---
.github/workflows/build.yml | 19 +
Makefile | 6 +-
cmd/aries-agent-mobile/go.sum | 2 +
cmd/aries-agent-rest/go.sum | 2 +
cmd/aries-js-worker/go.sum | 2 +
component/storage/edv/go.sum | 2 +
component/storage/indexeddb/go.sum | 2 +
go.mod | 3 +
go.sum | 2 +
.../tinkcrypto/primitive/cl/api/issuer.go | 19 +
.../tinkcrypto/primitive/cl/api/model.go | 144 +++++
.../tinkcrypto/primitive/cl/api/prover.go | 18 +
.../primitive/cl/issuer/cl_issuer_factory.go | 106 ++++
.../cl/issuer/cl_issuer_key_manager.go | 195 +++++++
.../cl/issuer/cl_issuer_key_manager_test.go | 260 +++++++++
.../cl/issuer/cl_issuer_key_template.go | 37 ++
.../cl/issuer/cl_issuer_key_template_test.go | 63 +++
.../tinkcrypto/primitive/cl/issuer/init.go | 27 +
.../primitive/cl/prover/cl_prover_factory.go | 110 ++++
.../cl/prover/cl_prover_key_manager.go | 147 +++++
.../cl/prover/cl_prover_key_manager_test.go | 169 ++++++
.../cl/prover/cl_prover_key_template.go | 32 ++
.../cl/prover/cl_prover_key_template_test.go | 73 +++
.../tinkcrypto/primitive/cl/prover/init.go | 26 +
.../primitive/cl/subtle/cl_issuer.go | 109 ++++
.../primitive/cl/subtle/cl_issuer_test.go | 76 +++
.../primitive/cl/subtle/cl_prover.go | 196 +++++++
.../primitive/cl/subtle/cl_prover_test.go | 116 ++++
.../tinkcrypto/primitive/cl/subtle/helper.go | 68 +++
.../primitive/cl/subtle/test_utils.go | 102 ++++
.../primitive/proto/cl_go_proto/cl.pb.go | 532 ++++++++++++++++++
proto/tink/cl.proto | 50 ++
scripts/check_unit_ursa.sh | 19 +
test/bdd/go.sum | 2 +
34 files changed, 2735 insertions(+), 1 deletion(-)
create mode 100644 pkg/crypto/tinkcrypto/primitive/cl/api/issuer.go
create mode 100644 pkg/crypto/tinkcrypto/primitive/cl/api/model.go
create mode 100644 pkg/crypto/tinkcrypto/primitive/cl/api/prover.go
create mode 100644 pkg/crypto/tinkcrypto/primitive/cl/issuer/cl_issuer_factory.go
create mode 100644 pkg/crypto/tinkcrypto/primitive/cl/issuer/cl_issuer_key_manager.go
create mode 100644 pkg/crypto/tinkcrypto/primitive/cl/issuer/cl_issuer_key_manager_test.go
create mode 100644 pkg/crypto/tinkcrypto/primitive/cl/issuer/cl_issuer_key_template.go
create mode 100644 pkg/crypto/tinkcrypto/primitive/cl/issuer/cl_issuer_key_template_test.go
create mode 100644 pkg/crypto/tinkcrypto/primitive/cl/issuer/init.go
create mode 100644 pkg/crypto/tinkcrypto/primitive/cl/prover/cl_prover_factory.go
create mode 100644 pkg/crypto/tinkcrypto/primitive/cl/prover/cl_prover_key_manager.go
create mode 100644 pkg/crypto/tinkcrypto/primitive/cl/prover/cl_prover_key_manager_test.go
create mode 100644 pkg/crypto/tinkcrypto/primitive/cl/prover/cl_prover_key_template.go
create mode 100644 pkg/crypto/tinkcrypto/primitive/cl/prover/cl_prover_key_template_test.go
create mode 100644 pkg/crypto/tinkcrypto/primitive/cl/prover/init.go
create mode 100644 pkg/crypto/tinkcrypto/primitive/cl/subtle/cl_issuer.go
create mode 100644 pkg/crypto/tinkcrypto/primitive/cl/subtle/cl_issuer_test.go
create mode 100644 pkg/crypto/tinkcrypto/primitive/cl/subtle/cl_prover.go
create mode 100644 pkg/crypto/tinkcrypto/primitive/cl/subtle/cl_prover_test.go
create mode 100644 pkg/crypto/tinkcrypto/primitive/cl/subtle/helper.go
create mode 100644 pkg/crypto/tinkcrypto/primitive/cl/subtle/test_utils.go
create mode 100755 pkg/crypto/tinkcrypto/primitive/proto/cl_go_proto/cl.pb.go
create mode 100644 proto/tink/cl.proto
create mode 100755 scripts/check_unit_ursa.sh
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 7a51b86ce..691256dff 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -42,6 +42,25 @@ jobs:
with:
file: ./coverage.out
+ unitTestUrsa:
+ name: Unit test (Ursa/CL)
+ runs-on: ubuntu-18.04
+ container:
+ image: ghcr.io/hyperledger/ursa-wrapper-go/uwg-build # a container with libursa installed
+ timeout-minutes: 15
+ steps:
+ - name: Setup Go 1.17
+ uses: actions/setup-go@v2
+ with:
+ go-version: 1.17
+ id: go
+
+ - uses: actions/checkout@v2
+
+ - name: Run unit test (Ursa/CL)
+ timeout-minutes: 15
+ run: make unit-test-ursa
+
unitTestMobile:
name: Unit test (mobile)
runs-on: ubuntu-18.04
diff --git a/Makefile b/Makefile
index 85e264812..a506f3397 100644
--- a/Makefile
+++ b/Makefile
@@ -27,7 +27,7 @@ MOCKGEN=$(GOBIN_PATH)/mockgen
GOMOCKS=pkg/internal/gomocks
.PHONY: all
-all: clean checks unit-test unit-test-wasm unit-test-mobile bdd-test
+all: clean checks unit-test unit-test-ursa unit-test-wasm unit-test-mobile bdd-test
.PHONY: checks
checks: license lint generate-openapi-spec
@@ -44,6 +44,10 @@ license:
unit-test: mocks
@scripts/check_unit.sh
+.PHONY: unit-test-ursa
+unit-test-ursa: mocks
+ @scripts/check_unit_ursa.sh
+
.PHONY: benchmark
benchmark:
@scripts/check_bench.sh
diff --git a/cmd/aries-agent-mobile/go.sum b/cmd/aries-agent-mobile/go.sum
index 40521a2d4..3ccf7ba68 100644
--- a/cmd/aries-agent-mobile/go.sum
+++ b/cmd/aries-agent-mobile/go.sum
@@ -189,6 +189,8 @@ github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-202206061
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220322085443-50e8f9bd208b/go.mod h1:HojN6OAh8ZtXBe5X2arcSOe1SLo5Dsjqto8ICjSLQ2g=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220428211718-66cc046674a1 h1:vxZ0DlFNLjgxMdBESLZu895AsI1JWL2SJerphwIn8Po=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220428211718-66cc046674a1/go.mod h1:lykx3N+GX+sAWSxO2Ycc4Dz+ynV9b0Fv4NdP+ms4Alc=
+github.com/hyperledger/ursa-wrapper-go v0.3.0 h1:ZYgPkPqy0AWEoU2Dhiziz91QacNdIX3j21UIOIVCXA8=
+github.com/hyperledger/ursa-wrapper-go v0.3.0/go.mod h1:nPSAuMasIzSVciQo22PedBk4Opph6bJ6ia3ms7BH/mk=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
diff --git a/cmd/aries-agent-rest/go.sum b/cmd/aries-agent-rest/go.sum
index 23b9b1d18..cee276d49 100644
--- a/cmd/aries-agent-rest/go.sum
+++ b/cmd/aries-agent-rest/go.sum
@@ -221,6 +221,8 @@ github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-202206061
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220322085443-50e8f9bd208b/go.mod h1:HojN6OAh8ZtXBe5X2arcSOe1SLo5Dsjqto8ICjSLQ2g=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220428211718-66cc046674a1 h1:vxZ0DlFNLjgxMdBESLZu895AsI1JWL2SJerphwIn8Po=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220428211718-66cc046674a1/go.mod h1:lykx3N+GX+sAWSxO2Ycc4Dz+ynV9b0Fv4NdP+ms4Alc=
+github.com/hyperledger/ursa-wrapper-go v0.3.0 h1:ZYgPkPqy0AWEoU2Dhiziz91QacNdIX3j21UIOIVCXA8=
+github.com/hyperledger/ursa-wrapper-go v0.3.0/go.mod h1:nPSAuMasIzSVciQo22PedBk4Opph6bJ6ia3ms7BH/mk=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
diff --git a/cmd/aries-js-worker/go.sum b/cmd/aries-js-worker/go.sum
index 8abf90c9d..8b8d1b719 100644
--- a/cmd/aries-js-worker/go.sum
+++ b/cmd/aries-js-worker/go.sum
@@ -187,6 +187,8 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220322085443-50e8f9bd208b/go.mod h1:HojN6OAh8ZtXBe5X2arcSOe1SLo5Dsjqto8ICjSLQ2g=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220428211718-66cc046674a1 h1:vxZ0DlFNLjgxMdBESLZu895AsI1JWL2SJerphwIn8Po=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220428211718-66cc046674a1/go.mod h1:lykx3N+GX+sAWSxO2Ycc4Dz+ynV9b0Fv4NdP+ms4Alc=
+github.com/hyperledger/ursa-wrapper-go v0.3.0 h1:ZYgPkPqy0AWEoU2Dhiziz91QacNdIX3j21UIOIVCXA8=
+github.com/hyperledger/ursa-wrapper-go v0.3.0/go.mod h1:nPSAuMasIzSVciQo22PedBk4Opph6bJ6ia3ms7BH/mk=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
diff --git a/component/storage/edv/go.sum b/component/storage/edv/go.sum
index 797908a5f..2fdd30b31 100644
--- a/component/storage/edv/go.sum
+++ b/component/storage/edv/go.sum
@@ -218,6 +218,8 @@ github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210820153043-8
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220217153004-1622c70e5767/go.mod h1:HojN6OAh8ZtXBe5X2arcSOe1SLo5Dsjqto8ICjSLQ2g=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220428211718-66cc046674a1 h1:vxZ0DlFNLjgxMdBESLZu895AsI1JWL2SJerphwIn8Po=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220428211718-66cc046674a1/go.mod h1:lykx3N+GX+sAWSxO2Ycc4Dz+ynV9b0Fv4NdP+ms4Alc=
+github.com/hyperledger/ursa-wrapper-go v0.3.0 h1:ZYgPkPqy0AWEoU2Dhiziz91QacNdIX3j21UIOIVCXA8=
+github.com/hyperledger/ursa-wrapper-go v0.3.0/go.mod h1:nPSAuMasIzSVciQo22PedBk4Opph6bJ6ia3ms7BH/mk=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
diff --git a/component/storage/indexeddb/go.sum b/component/storage/indexeddb/go.sum
index cf722c880..90cf4a46c 100644
--- a/component/storage/indexeddb/go.sum
+++ b/component/storage/indexeddb/go.sum
@@ -224,6 +224,8 @@ github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210820153043-8
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220217153004-1622c70e5767/go.mod h1:HojN6OAh8ZtXBe5X2arcSOe1SLo5Dsjqto8ICjSLQ2g=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220322085443-50e8f9bd208b h1:tq8CYv5vCJBSG2CjWKNt4l1BzZVJUy+GGF4U80fJV8o=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220322085443-50e8f9bd208b/go.mod h1:HojN6OAh8ZtXBe5X2arcSOe1SLo5Dsjqto8ICjSLQ2g=
+github.com/hyperledger/ursa-wrapper-go v0.3.0 h1:ZYgPkPqy0AWEoU2Dhiziz91QacNdIX3j21UIOIVCXA8=
+github.com/hyperledger/ursa-wrapper-go v0.3.0/go.mod h1:nPSAuMasIzSVciQo22PedBk4Opph6bJ6ia3ms7BH/mk=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
diff --git a/go.mod b/go.mod
index 76de95148..c6947f169 100644
--- a/go.mod
+++ b/go.mod
@@ -20,6 +20,7 @@ require (
github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220606124520-53422361c38c
github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220322085443-50e8f9bd208b
github.com/hyperledger/aries-framework-go/spi v0.0.0-20220606124520-53422361c38c
+ github.com/hyperledger/ursa-wrapper-go v0.3.0
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a
github.com/kawamuray/jsonpath v0.0.0-20201211160320-7483bafabd7e
github.com/kilic/bls12-381 v0.1.1-0.20210503002446-7b7597926c69
@@ -62,4 +63,6 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
)
+// replace github.com/hyperledger/ursa-wrapper-go => github.com/ashcherbakov/ursa-wrapper-go v0.3.1
+
go 1.17
diff --git a/go.sum b/go.sum
index a51e17466..8ba2fa5de 100644
--- a/go.sum
+++ b/go.sum
@@ -234,6 +234,8 @@ github.com/hyperledger/aries-framework-go/test/component v0.0.0-20210820153043-8
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220217153004-1622c70e5767/go.mod h1:HojN6OAh8ZtXBe5X2arcSOe1SLo5Dsjqto8ICjSLQ2g=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220428211718-66cc046674a1 h1:vxZ0DlFNLjgxMdBESLZu895AsI1JWL2SJerphwIn8Po=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220428211718-66cc046674a1/go.mod h1:lykx3N+GX+sAWSxO2Ycc4Dz+ynV9b0Fv4NdP+ms4Alc=
+github.com/hyperledger/ursa-wrapper-go v0.3.0 h1:ZYgPkPqy0AWEoU2Dhiziz91QacNdIX3j21UIOIVCXA8=
+github.com/hyperledger/ursa-wrapper-go v0.3.0/go.mod h1:nPSAuMasIzSVciQo22PedBk4Opph6bJ6ia3ms7BH/mk=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
diff --git a/pkg/crypto/tinkcrypto/primitive/cl/api/issuer.go b/pkg/crypto/tinkcrypto/primitive/cl/api/issuer.go
new file mode 100644
index 000000000..901275730
--- /dev/null
+++ b/pkg/crypto/tinkcrypto/primitive/cl/api/issuer.go
@@ -0,0 +1,19 @@
+//go:build ursa
+// +build ursa
+
+/*
+Copyright Avast Software. All Rights Reserved.
+
+SPDX-License-Identifier: Apache-2.0
+*/
+
+
+package api
+
+// Issuer is the signing interface primitive for CL signatures used by Tink.
+type Issuer interface {
+ GetCredentialDefinition() (*CredentialDefinition, error)
+ CreateCredentialOffer() (*CredentialOffer, error)
+ IssueCredential(values map[string]interface{}, credentialRequest *CredentialRequest, credOffer *CredentialOffer) (*Credential, error)
+ Free() error
+}
diff --git a/pkg/crypto/tinkcrypto/primitive/cl/api/model.go b/pkg/crypto/tinkcrypto/primitive/cl/api/model.go
new file mode 100644
index 000000000..9786f3f2a
--- /dev/null
+++ b/pkg/crypto/tinkcrypto/primitive/cl/api/model.go
@@ -0,0 +1,144 @@
+//go:build ursa
+// +build ursa
+
+/*
+Copyright Avast Software. All Rights Reserved.
+
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package api
+
+import (
+ "github.com/hyperledger/ursa-wrapper-go/pkg/libursa/ursa"
+)
+
+type CredentialDefinition struct {
+ CredPubKey *ursa.CredentialDefPubKey
+ CredDefCorrectnessProof *ursa.CredentialDefKeyCorrectnessProof
+ Attrs []string
+}
+
+func (s *CredentialDefinition) Free() error {
+ err := s.CredPubKey.Free()
+ if err != nil {
+ return err
+ }
+ err = s.CredDefCorrectnessProof.Free()
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+type CredentialOffer struct {
+ Nonce *ursa.Nonce
+}
+
+func (s *CredentialOffer) Free() error {
+ err := s.Nonce.Free()
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+type CredentialRequest struct {
+ BlindedCredentialSecrets *ursa.BlindedCredentialSecrets
+ Nonce *ursa.Nonce
+ ProverId string
+}
+
+func (s *CredentialRequest) Free() error {
+ err := s.BlindedCredentialSecrets.Handle.Free()
+ if err != nil {
+ return err
+ }
+ err = s.BlindedCredentialSecrets.BlindingFactor.Free()
+ if err != nil {
+ return err
+ }
+ err = s.BlindedCredentialSecrets.CorrectnessProof.Free()
+ if err != nil {
+ return err
+ }
+ err = s.Nonce.Free()
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+type Credential struct {
+ Signature *ursa.CredentialSignature
+ Values map[string]interface{}
+ SigProof *ursa.CredentialSignatureCorrectnessProof
+}
+
+func (s *Credential) Free() error {
+ err := s.Signature.Free()
+ if err != nil {
+ return err
+ }
+ err = s.SigProof.Free()
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+type PresentationRequest struct {
+ Items []*PresentationRequestItem
+ Nonce *ursa.Nonce
+}
+
+func (s *PresentationRequest) Free() error {
+ err := s.Nonce.Free()
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+type PresentationRequestItem struct {
+ RevealedAttrs []string
+ Predicates []*Predicate
+}
+
+type Predicate struct {
+ Attr string
+ PType string
+ Value int32
+}
+
+type Proof struct {
+ Proof *ursa.ProofHandle
+ SubProofs []*SubProof
+}
+
+func (s *Proof) Free() error {
+ err := s.Proof.Free()
+ if err != nil {
+ return err
+ }
+ for _, subProof := range s.SubProofs {
+ err = subProof.Free()
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+type SubProof struct {
+ SubProof *ursa.SubProofRequestHandle
+ Attrs []string
+}
+
+func (s *SubProof) Free() error {
+ err := s.SubProof.Free()
+ if err != nil {
+ return err
+ }
+ return nil
+}
diff --git a/pkg/crypto/tinkcrypto/primitive/cl/api/prover.go b/pkg/crypto/tinkcrypto/primitive/cl/api/prover.go
new file mode 100644
index 000000000..e699e5b8b
--- /dev/null
+++ b/pkg/crypto/tinkcrypto/primitive/cl/api/prover.go
@@ -0,0 +1,18 @@
+//go:build ursa
+// +build ursa
+
+/*
+Copyright Avast Software. All Rights Reserved.
+
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package api
+
+// Prover interface primitive for CL signatures used by Tink.
+type Prover interface {
+ CreateCredentialRequest(credOffer *CredentialOffer, credDef *CredentialDefinition, proverId string) (*CredentialRequest, error)
+ ProcessCredential(credential *Credential, credRequest *CredentialRequest, credDef *CredentialDefinition) error
+ CreateProof(presentationRequest *PresentationRequest, credentials []*Credential, credDefs []*CredentialDefinition) (*Proof, error)
+ Free() error
+}
diff --git a/pkg/crypto/tinkcrypto/primitive/cl/issuer/cl_issuer_factory.go b/pkg/crypto/tinkcrypto/primitive/cl/issuer/cl_issuer_factory.go
new file mode 100644
index 000000000..805502a64
--- /dev/null
+++ b/pkg/crypto/tinkcrypto/primitive/cl/issuer/cl_issuer_factory.go
@@ -0,0 +1,106 @@
+//go:build ursa
+// +build ursa
+
+/*
+Copyright Avast Software. All Rights Reserved.
+
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package issuer
+
+import (
+ "fmt"
+
+ "github.com/google/tink/go/core/primitiveset"
+ "github.com/google/tink/go/core/registry"
+ "github.com/google/tink/go/keyset"
+
+ clapi "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/cl/api"
+)
+
+// NewIssuer returns a CL Issuer primitive from the given keyset handle.
+func NewIssuer(h *keyset.Handle) (clapi.Issuer, error) {
+ return NewIssuerWithKeyManager(h, nil)
+}
+
+// NewIssuerWithKeyManager returns a CL Issuer primitive from the given keyset handle and custom key manager.
+func NewIssuerWithKeyManager(h *keyset.Handle, km registry.KeyManager) (clapi.Issuer, error) {
+ ps, err := h.PrimitivesWithKeyManager(km)
+ if err != nil {
+ return nil, fmt.Errorf("cl_issuer_factory: cannot obtain primitive set: %w", err)
+ }
+
+ return newWrappedIssuer(ps)
+}
+
+// wrappedIssuer is a CL Issuer implementation that uses the underlying primitive set for CL signing.
+type wrappedIssuer struct {
+ ps *primitiveset.PrimitiveSet
+}
+
+// newWrappedIssuer constructor creates a new wrappedIssuer and checks primitives in ps are all of CL Issuer type.
+func newWrappedIssuer(ps *primitiveset.PrimitiveSet) (*wrappedIssuer, error) {
+ if _, ok := (ps.Primary.Primitive).(clapi.Issuer); !ok {
+ return nil, fmt.Errorf("cl_issuer_factory: not a CL Issuer primitive")
+ }
+
+ for _, primitives := range ps.Entries {
+ for _, p := range primitives {
+ if _, ok := (p.Primitive).(clapi.Issuer); !ok {
+ return nil, fmt.Errorf("cl_issuer_factory: not a CL Issuer primitive")
+ }
+ }
+ }
+
+ ret := new(wrappedIssuer)
+ ret.ps = ps
+
+ return ret, nil
+}
+
+func (ws *wrappedIssuer) GetCredentialDefinition() (*clapi.CredentialDefinition, error) {
+ primary := ws.ps.Primary
+
+ issuer, ok := (primary.Primitive).(clapi.Issuer)
+ if !ok {
+ return nil, fmt.Errorf("cl_issuer_factory: not a CL Issuer primitive")
+ }
+
+ return issuer.GetCredentialDefinition()
+}
+
+func (ws *wrappedIssuer) CreateCredentialOffer() (*clapi.CredentialOffer, error) {
+ primary := ws.ps.Primary
+
+ issuer, ok := (primary.Primitive).(clapi.Issuer)
+ if !ok {
+ return nil, fmt.Errorf("cl_issuer_factory: not a CL Issuer primitive")
+ }
+
+ return issuer.CreateCredentialOffer()
+}
+
+func (ws *wrappedIssuer) IssueCredential(
+ values map[string]interface{}, credentialRequest *clapi.CredentialRequest, credOffer *clapi.CredentialOffer,
+) (*clapi.Credential, error) {
+ primary := ws.ps.Primary
+
+ issuer, ok := (primary.Primitive).(clapi.Issuer)
+ if !ok {
+ return nil, fmt.Errorf("cl_issuer_factory: not a CL Issuer primitive")
+ }
+
+ return issuer.IssueCredential(values, credentialRequest, credOffer)
+}
+
+func (ws *wrappedIssuer) Free() error {
+ primary := ws.ps.Primary
+
+ issuer, ok := (primary.Primitive).(clapi.Issuer)
+ if !ok {
+ return fmt.Errorf("cl_issuer_factory: not a CL Issuer primitive")
+ }
+
+ return issuer.Free()
+}
diff --git a/pkg/crypto/tinkcrypto/primitive/cl/issuer/cl_issuer_key_manager.go b/pkg/crypto/tinkcrypto/primitive/cl/issuer/cl_issuer_key_manager.go
new file mode 100644
index 000000000..ce5933099
--- /dev/null
+++ b/pkg/crypto/tinkcrypto/primitive/cl/issuer/cl_issuer_key_manager.go
@@ -0,0 +1,195 @@
+//go:build ursa
+// +build ursa
+
+/*
+Copyright Avast Software. All Rights Reserved.
+
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package issuer
+
+import (
+ "errors"
+ "fmt"
+
+ "github.com/golang/protobuf/proto"
+ "github.com/google/tink/go/keyset"
+ tinkpb "github.com/google/tink/go/proto/tink_go_proto"
+ clsubtle "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/cl/subtle"
+ clpb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/cl_go_proto"
+ "github.com/hyperledger/ursa-wrapper-go/pkg/libursa/ursa"
+)
+
+const (
+ clIssuerKeyVersion = 0
+ clIssuerKeyTypeURL = "type.hyperledger.org/hyperledger.aries.crypto.tink.CLIssuerKey"
+)
+
+// common errors.
+var (
+ errInvalidCLIssuerKey = errors.New("cl_issuer_key_manager: invalid cred def key")
+ errInvalidCLIssuerKeyFormat = errors.New("cl_issuer_key_manager: invalid cred def key format")
+ errInvalidKeyUrsa = errors.New("cl_issuer_key_manager: can not create Ursa cred def key")
+)
+
+// clIssuerKeyManager is an implementation of KeyManager interface for CL signatures/proofs.
+// It generates new CredDefPrivateKeys and produces new instances of CLIssuer subtle.
+type clIssuerKeyManager struct{}
+
+// Сreates a new clIssuerKeyManager.
+func newCLIssuerKeyManager() *clIssuerKeyManager {
+ return new(clIssuerKeyManager)
+}
+
+// Primitive creates a CL Issuer subtle for the given serialized CredDefPrivateKey proto.
+func (km *clIssuerKeyManager) Primitive(serializedKey []byte) (interface{}, error) {
+ if len(serializedKey) == 0 {
+ return nil, errInvalidCLIssuerKey
+ }
+
+ key := new(clpb.CLCredDefPrivateKey)
+
+ err := proto.Unmarshal(serializedKey, key)
+ if err != nil {
+ return nil, fmt.Errorf(errInvalidCLIssuerKey.Error()+": invalid proto: %w", err)
+ }
+
+ err = km.validateKey(key)
+ if err != nil {
+ return nil, fmt.Errorf(errInvalidCLIssuerKey.Error()+": %w", err)
+ }
+
+ clIssuer, err := clsubtle.NewCLIssuer(key.KeyValue, key.PublicKey.KeyValue, key.PublicKey.KeyCorrectnessProof, key.PublicKey.Params.Attrs)
+ if err != nil {
+ return nil, fmt.Errorf(errInvalidCLIssuerKey.Error()+": invalid ursa key: %w", err)
+ }
+
+ return clIssuer, nil
+}
+
+// NewKey creates a new key according to the specification of CLCredDefPrivateKey format.
+func (km *clIssuerKeyManager) NewKey(serializedKeyFormat []byte) (proto.Message, error) {
+ if len(serializedKeyFormat) == 0 {
+ return nil, errInvalidCLIssuerKeyFormat
+ }
+
+ // 1. Unmarshal to KeyFormat
+ keyFormat := new(clpb.CLCredDefKeyFormat)
+ err := proto.Unmarshal(serializedKeyFormat, keyFormat)
+ if err != nil {
+ return nil, fmt.Errorf(errInvalidCLIssuerKeyFormat.Error()+": invalid proto: %w", err)
+ }
+ err = validateKeyFormat(keyFormat)
+ if err != nil {
+ return nil, fmt.Errorf(errInvalidCLIssuerKeyFormat.Error()+": %w", err)
+ }
+
+ // 2. Create Credentials Schema
+ schema, nonSchema, err := clsubtle.BuildSchema(keyFormat.Params.Attrs)
+ if err != nil {
+ return nil, fmt.Errorf(errInvalidKeyUrsa.Error()+": %w", err)
+ }
+
+ // 4. Create CredDef
+ credDef, err := ursa.NewCredentialDef(schema, nonSchema, false)
+ if err != nil {
+ return nil, fmt.Errorf(errInvalidKeyUrsa.Error()+": %w", err)
+ }
+
+ // 5. serialize keys to JSONs
+ pubKeyBytes, err := credDef.PubKey.ToJSON()
+ if err != nil {
+ return nil, fmt.Errorf(errInvalidKeyUrsa.Error()+": can not convert cred def pub key to JSON: %w", err)
+ }
+ privKeyBytes, err := credDef.PrivKey.ToJSON()
+ if err != nil {
+ return nil, fmt.Errorf(errInvalidKeyUrsa.Error()+": can not convert cred def priv key to JSON: %w", err)
+ }
+ correctnessProofBytes, err := credDef.KeyCorrectnessProof.ToJSON()
+ if err != nil {
+ return nil, fmt.Errorf(errInvalidKeyUrsa.Error()+": can not convert cred def correctness proof to JSON: %w", err)
+ }
+
+ return &clpb.CLCredDefPrivateKey{
+ Version: clIssuerKeyVersion,
+ KeyValue: privKeyBytes,
+ PublicKey: &clpb.CLCredDefPublicKey{
+ Version: clIssuerKeyVersion,
+ Params: keyFormat.Params,
+ KeyValue: pubKeyBytes,
+ KeyCorrectnessProof: correctnessProofBytes,
+ },
+ }, nil
+}
+
+// NewKeyData creates a new KeyData according to the specification of CLCredDefPrivateKey Format.
+// It should be used solely by the key management API.
+func (km *clIssuerKeyManager) NewKeyData(serializedKeyFormat []byte) (*tinkpb.KeyData, error) {
+ key, err := km.NewKey(serializedKeyFormat)
+ if err != nil {
+ return nil, err
+ }
+
+ serializedKey, err := proto.Marshal(key)
+ if err != nil {
+ return nil, fmt.Errorf(errInvalidCLIssuerKeyFormat.Error()+": invalid proto: %w", err)
+ }
+
+ return &tinkpb.KeyData{
+ TypeUrl: clIssuerKeyTypeURL,
+ Value: serializedKey,
+ KeyMaterialType: tinkpb.KeyData_ASYMMETRIC_PRIVATE,
+ }, nil
+}
+
+// PublicKeyData returns the enclosed public key data of serializedPrivKey.
+func (km *clIssuerKeyManager) PublicKeyData(serializedPrivKey []byte) (*tinkpb.KeyData, error) {
+ privKey := new(clpb.CLCredDefPrivateKey)
+
+ err := proto.Unmarshal(serializedPrivKey, privKey)
+ if err != nil {
+ return nil, fmt.Errorf(errInvalidCLIssuerKey.Error()+": invalid proto: %w", err)
+ }
+
+ serializedPubKey, err := proto.Marshal(privKey.PublicKey)
+ if err != nil {
+ return nil, fmt.Errorf(errInvalidCLIssuerKey.Error()+": invalid proto: %w", err)
+ }
+
+ return &tinkpb.KeyData{
+ TypeUrl: clIssuerKeyTypeURL,
+ Value: serializedPubKey,
+ KeyMaterialType: tinkpb.KeyData_ASYMMETRIC_PUBLIC,
+ }, nil
+}
+
+// DoesSupport indicates if this key manager supports the given key type.
+func (km *clIssuerKeyManager) DoesSupport(typeURL string) bool {
+ return typeURL == clIssuerKeyTypeURL
+}
+
+// TypeURL returns the key type of keys managed by this key manager.
+func (km *clIssuerKeyManager) TypeURL() string {
+ return clIssuerKeyTypeURL
+}
+
+// validateKey validates the given CLCredDefPrivateKey
+func (km *clIssuerKeyManager) validateKey(key *clpb.CLCredDefPrivateKey) error {
+ err := keyset.ValidateKeyVersion(key.Version, clIssuerKeyVersion)
+ if err != nil {
+ return fmt.Errorf("invalid key version: %w", err)
+ }
+ return validateKeyParams(key.PublicKey.Params)
+}
+
+func validateKeyFormat(format *clpb.CLCredDefKeyFormat) error {
+ return validateKeyParams(format.Params)
+}
+
+func validateKeyParams(params *clpb.CLCredDefParams) error {
+ if len(params.Attrs) == 0 {
+ return fmt.Errorf("empty attributes")
+ }
+ return nil
+}
diff --git a/pkg/crypto/tinkcrypto/primitive/cl/issuer/cl_issuer_key_manager_test.go b/pkg/crypto/tinkcrypto/primitive/cl/issuer/cl_issuer_key_manager_test.go
new file mode 100644
index 000000000..9c82c8386
--- /dev/null
+++ b/pkg/crypto/tinkcrypto/primitive/cl/issuer/cl_issuer_key_manager_test.go
@@ -0,0 +1,260 @@
+//go:build ursa
+// +build ursa
+
+/*
+Copyright Avast Software. All Rights Reserved.
+
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package issuer
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/require"
+ "google.golang.org/protobuf/proto"
+
+ clsubtle "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/cl/subtle"
+ clpb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/cl_go_proto"
+)
+
+func TestCLIssuerKeyManager_Primitive(t *testing.T) {
+ km := newCLIssuerKeyManager()
+
+ t.Run("Test issuer key manager Primitive() success", func(t *testing.T) {
+ p, err := km.Primitive(getKey(t, validPrimitiveParams(t)))
+ require.NoError(t, err)
+ require.NotEmpty(t, p)
+ })
+
+ t.Run("Test issuer key manager Primitive() with empty serialized key", func(t *testing.T) {
+ p, err := km.Primitive([]byte(""))
+ require.EqualError(t, err, errInvalidCLIssuerKey.Error(),
+ "clIssuerKeyManager primitive from empty serialized key must fail")
+ require.Empty(t, p)
+ })
+
+ t.Run("Test issuer key manager Primitive() with bad serialize key", func(t *testing.T) {
+ p, err := km.Primitive([]byte("bad.data"))
+ require.Contains(t, err.Error(), errInvalidCLIssuerKey.Error())
+ require.Contains(t, err.Error(), "invalid proto: proto:")
+ require.Contains(t, err.Error(), "cannot parse invalid wire-format data")
+ require.Empty(t, p)
+ })
+
+ t.Run("Test issuer key manager Primitive() with bad version key", func(t *testing.T) {
+ p, err := km.Primitive(
+ getKey(t,
+ validPrimitiveParams(t).WithVersion(uint32(999)),
+ ),
+ )
+ require.Contains(t, err.Error(), errInvalidCLIssuerKey.Error())
+ require.Contains(t, err.Error(), "invalid key version")
+ require.Empty(t, p)
+ })
+
+ t.Run("Test issuer key manager Primitive() with empty attrs", func(t *testing.T) {
+ p, err := km.Primitive(
+ getKey(t,
+ validPrimitiveParams(t).WithAttrs([]string{}),
+ ),
+ )
+ require.Contains(t, err.Error(), errInvalidCLIssuerKey.Error())
+ require.Contains(t, err.Error(), "empty attributes")
+ require.Empty(t, p)
+ })
+
+ t.Run("Test issuer key manager Primitive() with invalid ursa private keys", func(t *testing.T) {
+ p, err := km.Primitive(
+ getKey(t,
+ validPrimitiveParams(t).WithPrivKey([]byte("bad data")),
+ ),
+ )
+ require.Contains(t, err.Error(), errInvalidCLIssuerKey.Error())
+ require.Contains(t, err.Error(), "invalid ursa key")
+ require.Contains(t, err.Error(), "invalid cred def private key")
+ require.Empty(t, p)
+ })
+
+ t.Run("Test issuer key manager Primitive() with invalid ursa public keys", func(t *testing.T) {
+ p, err := km.Primitive(
+ getKey(t,
+ validPrimitiveParams(t).WithPubKey([]byte("bad data")),
+ ),
+ )
+ require.Contains(t, err.Error(), errInvalidCLIssuerKey.Error())
+ require.Contains(t, err.Error(), "invalid ursa key")
+ require.Contains(t, err.Error(), "invalid cred def public key")
+ require.Empty(t, p)
+ })
+
+ t.Run("Test issuer key manager Primitive() with invalid ursa key proof", func(t *testing.T) {
+ p, err := km.Primitive(
+ getKey(t,
+ validPrimitiveParams(t).WithCorrectnessProof([]byte("bad data")),
+ ),
+ )
+ require.Contains(t, err.Error(), errInvalidCLIssuerKey.Error())
+ require.Contains(t, err.Error(), "invalid ursa key")
+ require.Contains(t, err.Error(), "invalid cred def correctness proof")
+ require.Empty(t, p)
+ })
+
+}
+
+func TestCLIssuerKeyManager_NewKey(t *testing.T) {
+ km := newCLIssuerKeyManager()
+
+ t.Run("Test issuer key manager NewKey() success", func(t *testing.T) {
+ p, err := km.NewKey(getSerializedKeyFormat(t, validPrimitiveParams(t)))
+ require.NoError(t, err)
+ require.NotEmpty(t, p)
+ })
+
+ t.Run("Test issuer key manager NewKey() with nil key", func(t *testing.T) {
+ k, err := km.NewKey(nil)
+ require.EqualError(t, err, errInvalidCLIssuerKeyFormat.Error())
+ require.Empty(t, k)
+ })
+
+ t.Run("Test issuer key manager NewKey() with bad serialize key", func(t *testing.T) {
+ p, err := km.NewKey([]byte("bad.data"))
+ require.Contains(t, err.Error(), errInvalidCLIssuerKeyFormat.Error())
+ require.Contains(t, err.Error(), "invalid proto: proto:")
+ require.Contains(t, err.Error(), "cannot parse invalid wire-format data")
+ require.Empty(t, p)
+ })
+
+ t.Run("Test issuer key manager NewKey() with empty attrs", func(t *testing.T) {
+ p, err := km.NewKey(
+ getSerializedKeyFormat(t,
+ validPrimitiveParams(t).WithAttrs([]string{}),
+ ),
+ )
+ require.Contains(t, err.Error(), errInvalidCLIssuerKey.Error())
+ require.Contains(t, err.Error(), "empty attributes")
+ require.Empty(t, p)
+ })
+}
+
+func TestCLIssuerKeyManager_NewKeyData(t *testing.T) {
+ km := newCLIssuerKeyManager()
+
+ t.Run("Test issuer key manager NewKeyData() success", func(t *testing.T) {
+ p, err := km.NewKeyData(getSerializedKeyFormat(t, validPrimitiveParams(t)))
+ require.NoError(t, err)
+ require.NotEmpty(t, p)
+ })
+
+ t.Run("Test issuer key manager NewKeyData() with nil key", func(t *testing.T) {
+ k, err := km.NewKeyData(nil)
+ require.EqualError(t, err, errInvalidCLIssuerKeyFormat.Error())
+ require.Empty(t, k)
+ })
+
+ t.Run("Test issuer key manager NewKeyData() with bad serialize key", func(t *testing.T) {
+ p, err := km.NewKeyData([]byte("bad.data"))
+ require.Contains(t, err.Error(), errInvalidCLIssuerKeyFormat.Error())
+ require.Contains(t, err.Error(), "invalid proto: proto:")
+ require.Contains(t, err.Error(), "cannot parse invalid wire-format data")
+ require.Empty(t, p)
+ })
+
+ t.Run("Test issuer key manager NewKeyData() with empty attrs", func(t *testing.T) {
+ p, err := km.NewKeyData(
+ getSerializedKeyFormat(t,
+ validPrimitiveParams(t).WithAttrs([]string{}),
+ ),
+ )
+ require.Contains(t, err.Error(), errInvalidCLIssuerKey.Error())
+ require.Contains(t, err.Error(), "empty attributes")
+ require.Empty(t, p)
+ })
+
+}
+
+func TestCLIssuerKeyManager_DoesSupport(t *testing.T) {
+ km := newCLIssuerKeyManager()
+ require.False(t, km.DoesSupport("bad/url"))
+ require.True(t, km.DoesSupport(clIssuerKeyTypeURL))
+}
+
+func TestCLIssuertKeyManager_TypeURL(t *testing.T) {
+ km := newCLIssuerKeyManager()
+ require.Equal(t, clIssuerKeyTypeURL, km.TypeURL())
+}
+
+type primitiveParams struct {
+ Version uint32
+ Attrs []string
+ PrivKey []byte
+ PubKey []byte
+ CorrectnessProof []byte
+}
+
+func validPrimitiveParams(t *testing.T) primitiveParams {
+ validVersion := uint32(0)
+ validPrivKey, validPubKey, proof, validAttrs := clsubtle.CreateCredentialDefinitionJson(t)
+ return primitiveParams{
+ Version: validVersion,
+ Attrs: validAttrs,
+ PrivKey: validPrivKey,
+ PubKey: validPubKey,
+ CorrectnessProof: proof,
+ }
+}
+
+func (pp primitiveParams) WithVersion(version uint32) primitiveParams {
+ pp.Version = version
+ return pp
+}
+
+func (pp primitiveParams) WithAttrs(attrs []string) primitiveParams {
+ pp.Attrs = attrs
+ return pp
+}
+
+func (pp primitiveParams) WithPrivKey(privKey []byte) primitiveParams {
+ pp.PrivKey = privKey
+ return pp
+}
+
+func (pp primitiveParams) WithPubKey(pubKey []byte) primitiveParams {
+ pp.PubKey = pubKey
+ return pp
+}
+
+func (pp primitiveParams) WithCorrectnessProof(proof []byte) primitiveParams {
+ pp.CorrectnessProof = proof
+ return pp
+}
+
+func getKey(t *testing.T, params primitiveParams) []byte {
+ privKey := &clpb.CLCredDefPrivateKey{
+ Version: params.Version,
+ KeyValue: params.PrivKey,
+ PublicKey: &clpb.CLCredDefPublicKey{
+ Version: params.Version,
+ Params: &clpb.CLCredDefParams{
+ Attrs: params.Attrs,
+ },
+ KeyValue: params.PubKey,
+ KeyCorrectnessProof: params.CorrectnessProof,
+ },
+ }
+ privKeyProto, err := proto.Marshal(privKey)
+ require.NoError(t, err)
+ return privKeyProto
+}
+
+func getSerializedKeyFormat(t *testing.T, params primitiveParams) []byte {
+ keyFormat := &clpb.CLCredDefKeyFormat{
+ Params: &clpb.CLCredDefParams{
+ Attrs: params.Attrs,
+ },
+ }
+ keyFormatProto, err := proto.Marshal(keyFormat)
+ require.NoError(t, err)
+ return keyFormatProto
+}
diff --git a/pkg/crypto/tinkcrypto/primitive/cl/issuer/cl_issuer_key_template.go b/pkg/crypto/tinkcrypto/primitive/cl/issuer/cl_issuer_key_template.go
new file mode 100644
index 000000000..2e61f91c9
--- /dev/null
+++ b/pkg/crypto/tinkcrypto/primitive/cl/issuer/cl_issuer_key_template.go
@@ -0,0 +1,37 @@
+//go:build ursa
+// +build ursa
+
+/*
+Copyright Avast Software. All Rights Reserved.
+
+SPDX-License-Identifier: Apache-2.0
+*/
+
+
+package issuer
+
+import (
+ tinkpb "github.com/google/tink/go/proto/tink_go_proto"
+ clpb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/cl_go_proto"
+ "google.golang.org/protobuf/proto"
+)
+
+// CL Cred Def key template.
+func CredDefKeyTemplate(attrs []string) *tinkpb.KeyTemplate {
+ format := &clpb.CLCredDefKeyFormat{
+ Params: &clpb.CLCredDefParams{
+ Attrs: attrs,
+ },
+ }
+
+ serializedFormat, err := proto.Marshal(format)
+ if err != nil {
+ panic("failed to marshal CLKeyFormat proto")
+ }
+
+ return &tinkpb.KeyTemplate{
+ TypeUrl: clIssuerKeyTypeURL,
+ Value: serializedFormat,
+ OutputPrefixType: tinkpb.OutputPrefixType_RAW,
+ }
+}
diff --git a/pkg/crypto/tinkcrypto/primitive/cl/issuer/cl_issuer_key_template_test.go b/pkg/crypto/tinkcrypto/primitive/cl/issuer/cl_issuer_key_template_test.go
new file mode 100644
index 000000000..3aaf05597
--- /dev/null
+++ b/pkg/crypto/tinkcrypto/primitive/cl/issuer/cl_issuer_key_template_test.go
@@ -0,0 +1,63 @@
+//go:build ursa
+// +build ursa
+
+/*
+Copyright Avast Software. All Rights Reserved.
+
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package issuer
+
+import (
+ "testing"
+
+ "github.com/google/tink/go/keyset"
+ "github.com/stretchr/testify/require"
+
+ clsubtle "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/cl/subtle"
+)
+
+func TestCLCredDefKeyTemplateSuccess(t *testing.T) {
+ attrs := []string{"attr1", "attr2"}
+ kt := CredDefKeyTemplate(attrs)
+ kh, err := keyset.NewHandle(kt)
+ require.NoError(t, err)
+ require.NotEmpty(t, kh)
+
+ pkHandle, err := kh.Public()
+ require.NoError(t, err)
+ require.NotEmpty(t, pkHandle)
+
+ // now test the CL primitives with these keyset handles
+ issuer, err := NewIssuer(kh)
+ defer issuer.Free()
+ require.NoError(t, err)
+ prover := clsubtle.NewTestCLProver(t)
+ defer prover.Free()
+
+ credDef, err := issuer.GetCredentialDefinition()
+ require.NoError(t, err)
+ require.NotEmpty(t, credDef.Attrs)
+ require.NotEmpty(t, credDef.CredPubKey)
+ require.NotEmpty(t, credDef.CredDefCorrectnessProof)
+
+ credOffer, err := issuer.CreateCredentialOffer()
+ defer credOffer.Free()
+ require.NoError(t, err)
+ require.NotEmpty(t, credOffer.Nonce)
+
+ credReq, err := prover.CreateCredentialRequest(credOffer, credDef, "proverID")
+ defer credReq.Free()
+ require.NoError(t, err)
+
+ values := clsubtle.NewTestValues(t, *credOffer)
+ cred, err := issuer.IssueCredential(values, credReq, credOffer)
+ defer cred.Free()
+
+ require.NoError(t, err)
+ require.NotEmpty(t, cred)
+ require.NotEmpty(t, cred.Signature)
+ require.NotEmpty(t, cred.Values)
+ require.NotEmpty(t, cred.SigProof)
+}
diff --git a/pkg/crypto/tinkcrypto/primitive/cl/issuer/init.go b/pkg/crypto/tinkcrypto/primitive/cl/issuer/init.go
new file mode 100644
index 000000000..7e3e2dec3
--- /dev/null
+++ b/pkg/crypto/tinkcrypto/primitive/cl/issuer/init.go
@@ -0,0 +1,27 @@
+//go:build ursa
+// +build ursa
+
+/*
+Copyright Avast Software. All Rights Reserved.
+
+SPDX-License-Identifier: Apache-2.0
+*/
+
+
+package issuer
+
+import (
+ "fmt"
+
+ "github.com/google/tink/go/core/registry"
+)
+
+// TODO - find a better way to setup tink than init.
+// nolint: gochecknoinits
+func init() {
+ // TODO - avoid the tink registry singleton.
+ err := registry.RegisterKeyManager(newCLIssuerKeyManager())
+ if err != nil {
+ panic(fmt.Sprintf("issuer.init() failed: %v", err))
+ }
+}
diff --git a/pkg/crypto/tinkcrypto/primitive/cl/prover/cl_prover_factory.go b/pkg/crypto/tinkcrypto/primitive/cl/prover/cl_prover_factory.go
new file mode 100644
index 000000000..1c738d4e0
--- /dev/null
+++ b/pkg/crypto/tinkcrypto/primitive/cl/prover/cl_prover_factory.go
@@ -0,0 +1,110 @@
+//go:build ursa
+// +build ursa
+
+/*
+Copyright Avast Software. All Rights Reserved.
+
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package prover
+
+import (
+ "fmt"
+
+ "github.com/google/tink/go/core/primitiveset"
+ "github.com/google/tink/go/core/registry"
+ "github.com/google/tink/go/keyset"
+
+ clapi "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/cl/api"
+)
+
+// NewProver returns a CL Prover primitive from the given keyset handle.
+func NewProver(h *keyset.Handle) (clapi.Prover, error) {
+ return NewProverWithKeyManager(h, nil)
+}
+
+// NewProverWithKeyManager returns a CL Prover primitive from the given keyset handle and custom key manager.
+func NewProverWithKeyManager(h *keyset.Handle, km registry.KeyManager) (clapi.Prover, error) {
+ ps, err := h.PrimitivesWithKeyManager(km)
+ if err != nil {
+ return nil, fmt.Errorf("cl_prover_factory: cannot obtain primitive set: %w", err)
+ }
+
+ return newWrappedProver(ps)
+}
+
+// wrappedProver is a CL Prover implementation that uses the underlying primitive set for CL prover.
+type wrappedProver struct {
+ ps *primitiveset.PrimitiveSet
+}
+
+// newWrappedProver constructor creates a new wrappedProver and checks primitives in ps are all of CL Prover type.
+func newWrappedProver(ps *primitiveset.PrimitiveSet) (*wrappedProver, error) {
+ if _, ok := (ps.Primary.Primitive).(clapi.Prover); !ok {
+ return nil, fmt.Errorf("cl_prover_factory: not a CL Prover primitive")
+ }
+
+ for _, primitives := range ps.Entries {
+ for _, p := range primitives {
+ if _, ok := (p.Primitive).(clapi.Prover); !ok {
+ return nil, fmt.Errorf("cl_prover_factory: not a CL Prover primitive")
+ }
+ }
+ }
+
+ ret := new(wrappedProver)
+ ret.ps = ps
+
+ return ret, nil
+}
+
+func (ws *wrappedProver) CreateCredentialRequest(
+ credOffer *clapi.CredentialOffer, credDef *clapi.CredentialDefinition, proverId string,
+) (*clapi.CredentialRequest, error) {
+ primary := ws.ps.Primary
+
+ prover, ok := (primary.Primitive).(clapi.Prover)
+ if !ok {
+ return nil, fmt.Errorf("cl_prover_factory: not a CL Prover primitive")
+ }
+
+ return prover.CreateCredentialRequest(credOffer, credDef, proverId)
+}
+
+func (ws *wrappedProver) ProcessCredential(
+ credential *clapi.Credential, credRequest *clapi.CredentialRequest, credDef *clapi.CredentialDefinition,
+) error {
+ primary := ws.ps.Primary
+
+ prover, ok := (primary.Primitive).(clapi.Prover)
+ if !ok {
+ return fmt.Errorf("cl_prover_factory: not a CL Prover primitive")
+ }
+
+ return prover.ProcessCredential(credential, credRequest, credDef)
+}
+
+func (ws *wrappedProver) CreateProof(
+ presentationRequest *clapi.PresentationRequest, credentials []*clapi.Credential, credDefs []*clapi.CredentialDefinition,
+) (*clapi.Proof, error) {
+ primary := ws.ps.Primary
+
+ prover, ok := (primary.Primitive).(clapi.Prover)
+ if !ok {
+ return nil, fmt.Errorf("cl_prover_factory: not a CL Prover primitive")
+ }
+
+ return prover.CreateProof(presentationRequest, credentials, credDefs)
+}
+
+func (ws *wrappedProver) Free() error {
+ primary := ws.ps.Primary
+
+ prover, ok := (primary.Primitive).(clapi.Prover)
+ if !ok {
+ return fmt.Errorf("cl_prover_factory: not a CL Issuer primitive")
+ }
+
+ return prover.Free()
+}
diff --git a/pkg/crypto/tinkcrypto/primitive/cl/prover/cl_prover_key_manager.go b/pkg/crypto/tinkcrypto/primitive/cl/prover/cl_prover_key_manager.go
new file mode 100644
index 000000000..31821553f
--- /dev/null
+++ b/pkg/crypto/tinkcrypto/primitive/cl/prover/cl_prover_key_manager.go
@@ -0,0 +1,147 @@
+//go:build ursa
+// +build ursa
+
+/*
+Copyright Avast Software. All Rights Reserved.
+
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package prover
+
+import (
+ "errors"
+ "fmt"
+
+ "github.com/golang/protobuf/proto"
+ "github.com/google/tink/go/keyset"
+ tinkpb "github.com/google/tink/go/proto/tink_go_proto"
+ clsubtle "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/cl/subtle"
+ clpb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/cl_go_proto"
+ "github.com/hyperledger/ursa-wrapper-go/pkg/libursa/ursa"
+)
+
+const (
+ clProverKeyVersion = 0
+ clProverKeyTypeURL = "type.hyperledger.org/hyperledger.aries.crypto.tink.CLProverKey"
+)
+
+// common errors.
+var (
+ errInvalidCLProverKey = errors.New("cl_prover_key_manager: invalid master secret key")
+ errInvalidCLProverKeyFormat = errors.New("cl_prover_key_manager: invalid master secret key format")
+ errInvalidKeyUrsa = errors.New("cl_prover_key_manager: can not create Ursa master secret key")
+)
+
+// clProverKeyManager is an implementation of KeyManager interface for CL signatures/proofs.
+// It generates new Master Secrets and produces new instances of CLProver subtle.
+type clProverKeyManager struct{}
+
+// Сreates a new clProverKeyManager.
+func newCLProverKeyManager() *clProverKeyManager {
+ return new(clProverKeyManager)
+}
+
+// Primitive creates a CL Prover subtle for the given serialized Master Secret proto.
+func (km *clProverKeyManager) Primitive(serializedKey []byte) (interface{}, error) {
+ if len(serializedKey) == 0 {
+ return nil, errInvalidCLProverKey
+ }
+
+ key := new(clpb.CLMasterSecret)
+
+ err := proto.Unmarshal(serializedKey, key)
+ if err != nil {
+ return nil, fmt.Errorf(errInvalidCLProverKey.Error()+": invalid proto: %w", err)
+ }
+
+ err = km.validateKey(key)
+ if err != nil {
+ return nil, fmt.Errorf(errInvalidCLProverKey.Error()+": %w", err)
+ }
+
+ clProver, err := clsubtle.NewCLProver(key.KeyValue)
+ if err != nil {
+ return nil, fmt.Errorf(errInvalidCLProverKey.Error()+": invalid ursa key: %w", err)
+ }
+
+ return clProver, nil
+}
+
+// NewKey creates a new key according to the specification of CLMasterSecretKeyFormat format.
+func (km *clProverKeyManager) NewKey(serializedKeyFormat []byte) (proto.Message, error) {
+ if serializedKeyFormat == nil {
+ return nil, errInvalidCLProverKeyFormat
+ }
+
+ // 1. Unmarshal to KeyFormat
+ keyFormat := new(clpb.CLMasterSecretKeyFormat)
+ err := proto.Unmarshal(serializedKeyFormat, keyFormat)
+ if err != nil {
+ return nil, fmt.Errorf(errInvalidCLProverKeyFormat.Error()+": invalid proto: %w", err)
+ }
+ err = validateKeyFormat(keyFormat)
+ if err != nil {
+ return nil, fmt.Errorf(errInvalidCLProverKey.Error()+": %w", err)
+ }
+
+ // 2. Create Master Secret
+ ms, err := ursa.NewMasterSecret()
+ if err != nil {
+ return nil, fmt.Errorf(errInvalidKeyUrsa.Error()+": %w", err)
+ }
+
+ // 3. serialize keys to JSONs
+ msBytes, err := ms.ToJSON()
+ if err != nil {
+ return nil, fmt.Errorf(errInvalidKeyUrsa.Error()+": can not convert master secret to JSON: %w", err)
+ }
+
+ return &clpb.CLMasterSecret{
+ Version: clProverKeyVersion,
+ KeyValue: msBytes,
+ }, nil
+}
+
+// NewKeyData creates a new KeyData according to the specification of CLMasterSecret Format.
+// It should be used solely by the key management API.
+func (km *clProverKeyManager) NewKeyData(serializedKeyFormat []byte) (*tinkpb.KeyData, error) {
+ key, err := km.NewKey(serializedKeyFormat)
+ if err != nil {
+ return nil, err
+ }
+
+ serializedKey, err := proto.Marshal(key)
+ if err != nil {
+ return nil, fmt.Errorf(errInvalidCLProverKeyFormat.Error()+": invalid proto: %w", err)
+ }
+
+ return &tinkpb.KeyData{
+ TypeUrl: clProverKeyTypeURL,
+ Value: serializedKey,
+ KeyMaterialType: tinkpb.KeyData_SYMMETRIC,
+ }, nil
+}
+
+// DoesSupport indicates if this key manager supports the given key type.
+func (km *clProverKeyManager) DoesSupport(typeURL string) bool {
+ return typeURL == clProverKeyTypeURL
+}
+
+// TypeURL returns the key type of keys managed by this key manager.
+func (km *clProverKeyManager) TypeURL() string {
+ return clProverKeyTypeURL
+}
+
+// validateKey validates the given CLCredDefPrivateKey
+func (km *clProverKeyManager) validateKey(key *clpb.CLMasterSecret) error {
+ err := keyset.ValidateKeyVersion(key.Version, clProverKeyVersion)
+ if err != nil {
+ return fmt.Errorf("invalid key version: %w", err)
+ }
+ return nil
+}
+
+func validateKeyFormat(format *clpb.CLMasterSecretKeyFormat) error {
+ return nil
+}
diff --git a/pkg/crypto/tinkcrypto/primitive/cl/prover/cl_prover_key_manager_test.go b/pkg/crypto/tinkcrypto/primitive/cl/prover/cl_prover_key_manager_test.go
new file mode 100644
index 000000000..f4cdae0ca
--- /dev/null
+++ b/pkg/crypto/tinkcrypto/primitive/cl/prover/cl_prover_key_manager_test.go
@@ -0,0 +1,169 @@
+//go:build ursa
+// +build ursa
+
+/*
+Copyright Avast Software. All Rights Reserved.
+
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package prover
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/require"
+ "google.golang.org/protobuf/proto"
+
+ clsubtle "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/cl/subtle"
+ clpb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/cl_go_proto"
+)
+
+func TestCLProverKeyManager_Primitive(t *testing.T) {
+ km := newCLProverKeyManager()
+
+ t.Run("Test prover key manager Primitive() success", func(t *testing.T) {
+ p, err := km.Primitive(getKey(t, validPrimitiveParams(t)))
+ require.NoError(t, err)
+ require.NotEmpty(t, p)
+ })
+
+ t.Run("Test prover key manager Primitive() with nil serialized key", func(t *testing.T) {
+ p, err := km.Primitive(nil)
+ require.Contains(t, err.Error(), errInvalidCLProverKey.Error())
+ require.Empty(t, p)
+ })
+
+ t.Run("Test prover key manager Primitive() with bad serialize key", func(t *testing.T) {
+ p, err := km.Primitive([]byte("bad.data"))
+ require.Contains(t, err.Error(), errInvalidCLProverKey.Error())
+ require.Contains(t, err.Error(), "invalid proto: proto:")
+ require.Contains(t, err.Error(), "cannot parse invalid wire-format data")
+ require.Empty(t, p)
+ })
+
+ t.Run("Test prover key manager Primitive() with bad version key", func(t *testing.T) {
+ p, err := km.Primitive(
+ getKey(t,
+ validPrimitiveParams(t).WithVersion(uint32(999)),
+ ),
+ )
+ require.Contains(t, err.Error(), errInvalidCLProverKey.Error())
+ require.Contains(t, err.Error(), "invalid key version")
+ require.Empty(t, p)
+ })
+
+ t.Run("Test prover key manager Primitive() with invalid ursa key", func(t *testing.T) {
+ p, err := km.Primitive(
+ getKey(t,
+ validPrimitiveParams(t).WithKey([]byte("bad data")),
+ ),
+ )
+ require.Contains(t, err.Error(), errInvalidCLProverKey.Error())
+ require.Contains(t, err.Error(), "invalid ursa key")
+ require.Contains(t, err.Error(), "invalid master secret key")
+ require.Empty(t, p)
+ })
+
+}
+
+func TestCLProverKeyManager_NewKey(t *testing.T) {
+ km := newCLProverKeyManager()
+
+ t.Run("Test prover key manager NewKey() success", func(t *testing.T) {
+ p, err := km.NewKey(getSerializedKeyFormat(t, validPrimitiveParams(t)))
+ require.NoError(t, err)
+ require.NotEmpty(t, p)
+ })
+
+ t.Run("Test prover key manager NewKey() with nil key", func(t *testing.T) {
+ k, err := km.NewKey(nil)
+ require.EqualError(t, err, errInvalidCLProverKeyFormat.Error())
+ require.Empty(t, k)
+ })
+
+ t.Run("Test prover key manager NewKey() with bad serialize key", func(t *testing.T) {
+ p, err := km.NewKey([]byte("bad.data"))
+ require.Contains(t, err.Error(), errInvalidCLProverKeyFormat.Error())
+ require.Contains(t, err.Error(), "invalid proto: proto:")
+ require.Contains(t, err.Error(), "cannot parse invalid wire-format data")
+ require.Empty(t, p)
+ })
+}
+
+func TestCLProverKeyManager_NewKeyData(t *testing.T) {
+ km := newCLProverKeyManager()
+
+ t.Run("Test prover key manager NewKeyData() success", func(t *testing.T) {
+ p, err := km.NewKeyData(getSerializedKeyFormat(t, validPrimitiveParams(t)))
+ require.NoError(t, err)
+ require.NotEmpty(t, p)
+ })
+
+ t.Run("Test prover key manager NewKeyData() with nil key", func(t *testing.T) {
+ k, err := km.NewKeyData(nil)
+ require.EqualError(t, err, errInvalidCLProverKeyFormat.Error())
+ require.Empty(t, k)
+ })
+
+ t.Run("Test prover key manager NewKeyData() with bad serialize key", func(t *testing.T) {
+ p, err := km.NewKeyData([]byte("bad.data"))
+ require.Contains(t, err.Error(), errInvalidCLProverKeyFormat.Error())
+ require.Contains(t, err.Error(), "invalid proto: proto:")
+ require.Contains(t, err.Error(), "cannot parse invalid wire-format data")
+ require.Empty(t, p)
+ })
+
+}
+
+func TestCLProverKeyManager_DoesSupport(t *testing.T) {
+ km := newCLProverKeyManager()
+ require.False(t, km.DoesSupport("bad/url"))
+ require.True(t, km.DoesSupport(clProverKeyTypeURL))
+}
+
+func TestCLProverKeyManager_TypeURL(t *testing.T) {
+ km := newCLProverKeyManager()
+ require.Equal(t, clProverKeyTypeURL, km.TypeURL())
+}
+
+type primitiveParams struct {
+ Version uint32
+ Key []byte
+}
+
+func validPrimitiveParams(t *testing.T) primitiveParams {
+ validVersion := uint32(0)
+ validKey := clsubtle.CreateMasterSecretKeyJson(t)
+ return primitiveParams{
+ Version: validVersion,
+ Key: validKey,
+ }
+}
+
+func (pp primitiveParams) WithVersion(version uint32) primitiveParams {
+ pp.Version = version
+ return pp
+}
+
+func (pp primitiveParams) WithKey(key []byte) primitiveParams {
+ pp.Key = key
+ return pp
+}
+
+func getKey(t *testing.T, params primitiveParams) []byte {
+ ms := &clpb.CLMasterSecret{
+ Version: params.Version,
+ KeyValue: params.Key,
+ }
+ msKeyProto, err := proto.Marshal(ms)
+ require.NoError(t, err)
+ return msKeyProto
+}
+
+func getSerializedKeyFormat(t *testing.T, params primitiveParams) []byte {
+ keyFormat := &clpb.CLMasterSecretKeyFormat{}
+ keyFormatProto, err := proto.Marshal(keyFormat)
+ require.NoError(t, err)
+ return keyFormatProto
+}
diff --git a/pkg/crypto/tinkcrypto/primitive/cl/prover/cl_prover_key_template.go b/pkg/crypto/tinkcrypto/primitive/cl/prover/cl_prover_key_template.go
new file mode 100644
index 000000000..7bf95dfdd
--- /dev/null
+++ b/pkg/crypto/tinkcrypto/primitive/cl/prover/cl_prover_key_template.go
@@ -0,0 +1,32 @@
+//go:build ursa
+// +build ursa
+
+/*
+Copyright Avast Software. All Rights Reserved.
+
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package prover
+
+import (
+ tinkpb "github.com/google/tink/go/proto/tink_go_proto"
+ clpb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/cl_go_proto"
+ "google.golang.org/protobuf/proto"
+)
+
+// CL Master Secret key template.
+func MasterSecretKeyTemplate() *tinkpb.KeyTemplate {
+ format := &clpb.CLMasterSecretKeyFormat{}
+
+ serializedFormat, err := proto.Marshal(format)
+ if err != nil {
+ panic("failed to marshal CLMasterSecret proto")
+ }
+
+ return &tinkpb.KeyTemplate{
+ TypeUrl: clProverKeyTypeURL,
+ Value: serializedFormat,
+ OutputPrefixType: tinkpb.OutputPrefixType_RAW,
+ }
+}
diff --git a/pkg/crypto/tinkcrypto/primitive/cl/prover/cl_prover_key_template_test.go b/pkg/crypto/tinkcrypto/primitive/cl/prover/cl_prover_key_template_test.go
new file mode 100644
index 000000000..64dd2f457
--- /dev/null
+++ b/pkg/crypto/tinkcrypto/primitive/cl/prover/cl_prover_key_template_test.go
@@ -0,0 +1,73 @@
+//go:build ursa
+// +build ursa
+
+/*
+Copyright Avast Software. All Rights Reserved.
+
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package prover
+
+import (
+ "testing"
+
+ "github.com/google/tink/go/keyset"
+ "github.com/stretchr/testify/require"
+
+ clapi "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/cl/api"
+ clsubtle "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/cl/subtle"
+)
+
+func TestCLMasterSecretKeyTemplateSuccess(t *testing.T) {
+ kt := MasterSecretKeyTemplate()
+ kh, err := keyset.NewHandle(kt)
+ require.NoError(t, err)
+ require.NotEmpty(t, kh)
+
+ // now test the CL primitives with these keyset handles
+ prover, err := NewProver(kh)
+ defer prover.Free()
+ require.NoError(t, err)
+ issuer := clsubtle.NewTestCLIssuer(t)
+ defer issuer.Free()
+
+ credDef, err := issuer.GetCredentialDefinition()
+ require.NoError(t, err)
+
+ credOffer, err := issuer.CreateCredentialOffer()
+ defer credOffer.Free()
+ require.NoError(t, err)
+
+ credReq, err := prover.CreateCredentialRequest(credOffer, credDef, "myproverID")
+ defer credReq.Free()
+ require.NoError(t, err)
+ require.NotEmpty(t, credReq.Nonce)
+ require.NotEmpty(t, credReq.BlindedCredentialSecrets)
+ require.Equal(t, "myproverID", credReq.ProverId)
+
+ values := clsubtle.NewTestValues(t, *credOffer)
+ cred, err := issuer.IssueCredential(values, credReq, credOffer)
+ defer cred.Free()
+ require.NoError(t, err)
+
+ err = prover.ProcessCredential(cred, credReq, credDef)
+ require.NoError(t, err)
+
+ presReq := clsubtle.NewTestPresentationRequest(t)
+ defer presReq.Free()
+
+ proof, err := prover.CreateProof(presReq, []*clapi.Credential{cred}, []*clapi.CredentialDefinition{credDef})
+ defer proof.Free()
+
+ require.NoError(t, err)
+ require.NotEmpty(t, proof)
+ require.NotEmpty(t, proof.Proof)
+ require.NotEmpty(t, proof.SubProofs)
+ require.NotEmpty(t, proof.SubProofs[0])
+ require.NotEmpty(t, proof.SubProofs[0].Attrs)
+ require.NotEmpty(t, proof.SubProofs[0].SubProof)
+
+ err = clsubtle.Verify(t, presReq, proof, credDef)
+ require.NoError(t, err)
+}
diff --git a/pkg/crypto/tinkcrypto/primitive/cl/prover/init.go b/pkg/crypto/tinkcrypto/primitive/cl/prover/init.go
new file mode 100644
index 000000000..72910468d
--- /dev/null
+++ b/pkg/crypto/tinkcrypto/primitive/cl/prover/init.go
@@ -0,0 +1,26 @@
+//go:build ursa
+// +build ursa
+
+/*
+Copyright Avast Software. All Rights Reserved.
+
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package prover
+
+import (
+ "fmt"
+
+ "github.com/google/tink/go/core/registry"
+)
+
+// TODO - find a better way to setup tink than init.
+// nolint: gochecknoinits
+func init() {
+ // TODO - avoid the tink registry singleton.
+ err := registry.RegisterKeyManager(newCLProverKeyManager())
+ if err != nil {
+ panic(fmt.Sprintf("prover.init() failed: %v", err))
+ }
+}
diff --git a/pkg/crypto/tinkcrypto/primitive/cl/subtle/cl_issuer.go b/pkg/crypto/tinkcrypto/primitive/cl/subtle/cl_issuer.go
new file mode 100644
index 000000000..29aba5169
--- /dev/null
+++ b/pkg/crypto/tinkcrypto/primitive/cl/subtle/cl_issuer.go
@@ -0,0 +1,109 @@
+//go:build ursa
+// +build ursa
+
+/*
+Copyright Avast Software. All Rights Reserved.
+
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package subtle
+
+import (
+ "fmt"
+
+ clapi "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/cl/api"
+ "github.com/hyperledger/ursa-wrapper-go/pkg/libursa/ursa"
+)
+
+// CL Issuer (Signer)
+type CLIssuer struct {
+ pubKey *ursa.CredentialDefPubKey
+ privKey *ursa.CredentialDefPrivKey
+ correctnessProof *ursa.CredentialDefKeyCorrectnessProof
+ attrs []string
+}
+
+// Creates a new instance of CLIssuer with the provided privateKey.
+func NewCLIssuer(privKey []byte, pubKey []byte, correctnessProof []byte, attrs []string) (*CLIssuer, error) {
+ clPubKey, err := ursa.CredentialPublicKeyFromJSON(pubKey)
+ if err != nil {
+ return nil, fmt.Errorf("cl_issuer: invalid cred def public key json: %w", err)
+ }
+ clPrivKey, err := ursa.CredentialPrivateKeyFromJSON(privKey)
+ if err != nil {
+ return nil, fmt.Errorf("cl_issuer: invalid cred def private key json: %w", err)
+ }
+ clCorrecrtnessProof, err := ursa.CredentialKeyCorrectnessProofFromJSON(correctnessProof)
+ if err != nil {
+ return nil, fmt.Errorf("cl_issuer: invalid cred def correctness proof json: %w", err)
+ }
+
+ return &CLIssuer{
+ pubKey: clPubKey,
+ privKey: clPrivKey,
+ correctnessProof: clCorrecrtnessProof,
+ attrs: attrs,
+ }, nil
+}
+
+func (s *CLIssuer) GetCredentialDefinition() (*clapi.CredentialDefinition, error) {
+ return &clapi.CredentialDefinition{
+ CredPubKey: s.pubKey,
+ CredDefCorrectnessProof: s.correctnessProof,
+ Attrs: s.attrs,
+ }, nil
+}
+
+func (s *CLIssuer) CreateCredentialOffer() (*clapi.CredentialOffer, error) {
+ nonce, err := ursa.NewNonce()
+ if err != nil {
+ return nil, err
+ }
+ return &clapi.CredentialOffer{
+ Nonce: nonce,
+ }, nil
+}
+
+func (s *CLIssuer) IssueCredential(
+ values map[string]interface{}, credentialRequest *clapi.CredentialRequest, credOffer *clapi.CredentialOffer,
+) (*clapi.Credential, error) {
+ credentialValues, err := BuildValues(values, nil)
+ if err != nil {
+ return nil, err
+ }
+ defer credentialValues.Free()
+
+ signParams := ursa.NewSignatureParams()
+ signParams.ProverID = credentialRequest.ProverId
+ signParams.CredentialPubKey = s.pubKey
+ signParams.CredentialPrivKey = s.privKey
+ signParams.BlindedCredentialSecrets = credentialRequest.BlindedCredentialSecrets.Handle
+ signParams.BlindedCredentialSecretsCorrectnessProof = credentialRequest.BlindedCredentialSecrets.CorrectnessProof
+ signParams.CredentialNonce = credOffer.Nonce
+ signParams.CredentialValues = credentialValues
+ signParams.CredentialIssuanceNonce = credentialRequest.Nonce
+
+ sig, sigCorrectnessProof, err := signParams.SignCredential()
+ return &clapi.Credential{
+ Signature: sig,
+ SigProof: sigCorrectnessProof,
+ Values: values,
+ }, err
+}
+
+func (s *CLIssuer) Free() error {
+ err := s.correctnessProof.Free()
+ if err != nil {
+ return err
+ }
+ err = s.privKey.Free()
+ if err != nil {
+ return err
+ }
+ err = s.pubKey.Free()
+ if err != nil {
+ return err
+ }
+ return nil
+}
diff --git a/pkg/crypto/tinkcrypto/primitive/cl/subtle/cl_issuer_test.go b/pkg/crypto/tinkcrypto/primitive/cl/subtle/cl_issuer_test.go
new file mode 100644
index 000000000..02e1f9459
--- /dev/null
+++ b/pkg/crypto/tinkcrypto/primitive/cl/subtle/cl_issuer_test.go
@@ -0,0 +1,76 @@
+//go:build ursa
+// +build ursa
+
+/*
+Copyright Avast Software. All Rights Reserved.
+
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package subtle
+
+import (
+ "testing"
+
+ clapi "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/cl/api"
+ "github.com/stretchr/testify/require"
+)
+
+func TestIsCLIssuer(t *testing.T) {
+ clIssuer := NewTestCLIssuer(t)
+ defer clIssuer.Free()
+
+ _, ok := interface{}(clIssuer).(clapi.Issuer)
+ require.True(t, ok)
+}
+
+func TestGetCredentialDefinition(t *testing.T) {
+ clIssuer := NewTestCLIssuer(t)
+ defer clIssuer.Free()
+
+ credDef, err := clIssuer.GetCredentialDefinition()
+
+ require.NoError(t, err)
+ require.NotEmpty(t, credDef.Attrs)
+ require.NotEmpty(t, credDef.CredPubKey)
+ require.NotEmpty(t, credDef.CredDefCorrectnessProof)
+}
+
+func TestCreateCredOffer(t *testing.T) {
+ clIssuer := NewTestCLIssuer(t)
+ defer clIssuer.Free()
+
+ credOffer, err := clIssuer.CreateCredentialOffer()
+ defer credOffer.Free()
+
+ require.NoError(t, err)
+ require.NotEmpty(t, credOffer.Nonce)
+}
+
+func TestIssueCredential(t *testing.T) {
+ clIssuer := NewTestCLIssuer(t)
+ defer clIssuer.Free()
+ clProver := NewTestCLProver(t)
+ defer clProver.Free()
+
+ credDef, err := clIssuer.GetCredentialDefinition()
+ require.NoError(t, err)
+
+ credOffer, err := clIssuer.CreateCredentialOffer()
+ defer credOffer.Free()
+ require.NoError(t, err)
+
+ credReq, err := clProver.CreateCredentialRequest(credOffer, credDef, "proverID")
+ defer credReq.Free()
+ require.NoError(t, err)
+
+ values := NewTestValues(t, *credOffer)
+ cred, err := clIssuer.IssueCredential(values, credReq, credOffer)
+ defer cred.Free()
+
+ require.NoError(t, err)
+ require.NotEmpty(t, cred)
+ require.NotEmpty(t, cred.Signature)
+ require.NotEmpty(t, cred.Values)
+ require.NotEmpty(t, cred.SigProof)
+}
diff --git a/pkg/crypto/tinkcrypto/primitive/cl/subtle/cl_prover.go b/pkg/crypto/tinkcrypto/primitive/cl/subtle/cl_prover.go
new file mode 100644
index 000000000..ba79a17b4
--- /dev/null
+++ b/pkg/crypto/tinkcrypto/primitive/cl/subtle/cl_prover.go
@@ -0,0 +1,196 @@
+//go:build ursa
+// +build ursa
+
+/*
+Copyright Avast Software. All Rights Reserved.
+
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package subtle
+
+import (
+ "encoding/json"
+ "fmt"
+
+ clapi "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/cl/api"
+ "github.com/hyperledger/ursa-wrapper-go/pkg/libursa/ursa"
+)
+
+// CL Prover
+type CLProver struct {
+ masterSecret *ursa.MasterSecret
+ masterSecretStr string
+}
+
+// Creates a new instance of CL Prover with the provided privateKey.
+func NewCLProver(key []byte) (*CLProver, error) {
+ ms, err := ursa.MasterSecretFromJSON(key)
+ if err != nil {
+ return nil, fmt.Errorf("cl_prover: invalid master secret json: %w", err)
+ }
+
+ msJson, err := ms.ToJSON()
+ if err != nil {
+ return nil, err
+ }
+ m := struct {
+ MS string `json:"ms"`
+ }{}
+ err = json.Unmarshal(msJson, &m)
+ if err != nil {
+ return nil, err
+ }
+
+ return &CLProver{
+ masterSecret: ms,
+ masterSecretStr: m.MS,
+ }, nil
+}
+
+func (s *CLProver) CreateCredentialRequest(
+ credOffer *clapi.CredentialOffer, credDef *clapi.CredentialDefinition, proverId string,
+) (*clapi.CredentialRequest, error) {
+ credentialValues, err := BuildValues(map[string]interface{}{}, &s.masterSecretStr)
+ if err != nil {
+ return nil, err
+ }
+ defer credentialValues.Free()
+
+ blindedCredSecret, err := ursa.BlindCredentialSecrets(
+ credDef.CredPubKey, credDef.CredDefCorrectnessProof, credOffer.Nonce, credentialValues,
+ )
+ if err != nil {
+ return nil, err
+ }
+
+ credReqNonce, err := ursa.NewNonce()
+ if err != nil {
+ return nil, err
+ }
+
+ return &clapi.CredentialRequest{
+ BlindedCredentialSecrets: blindedCredSecret,
+ Nonce: credReqNonce,
+ ProverId: proverId,
+ }, nil
+}
+
+func (s *CLProver) ProcessCredential(
+ credential *clapi.Credential, credRequest *clapi.CredentialRequest, credDef *clapi.CredentialDefinition,
+) error {
+ credentialValues, err := BuildValues(credential.Values, &s.masterSecretStr)
+ if err != nil {
+ return err
+ }
+ defer credentialValues.Free()
+
+ return credential.Signature.ProcessCredentialSignature(
+ credentialValues,
+ credential.SigProof,
+ credRequest.BlindedCredentialSecrets.BlindingFactor,
+ credDef.CredPubKey,
+ credRequest.Nonce,
+ )
+}
+
+func (s *CLProver) CreateProof(
+ presentationRequest *clapi.PresentationRequest, credentials []*clapi.Credential, credDefs []*clapi.CredentialDefinition,
+) (*clapi.Proof, error) {
+ if len(presentationRequest.Items) != len(credentials) {
+ return nil, fmt.Errorf("Not enough credentials provided to fulfill the presentsation request")
+ }
+ if len(presentationRequest.Items) != len(credDefs) {
+ return nil, fmt.Errorf("Not enough credential definitions provided to fulfill the presentsation request")
+ }
+ subProofRequests := make([]*ursa.SubProofRequestHandle, len(presentationRequest.Items))
+ for i, presentationRequest := range presentationRequest.Items {
+ subProofBuilder, err := ursa.NewSubProofRequestBuilder()
+ if err != nil {
+ return nil, err
+ }
+ for _, revealedAttr := range presentationRequest.RevealedAttrs {
+ err = subProofBuilder.AddRevealedAttr(revealedAttr)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ for _, predicate := range presentationRequest.Predicates {
+ err = subProofBuilder.AddPredicate(predicate.Attr, predicate.PType, predicate.Value)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ subProofRequest, err := subProofBuilder.Finalize()
+ if err != nil {
+ return nil, err
+ }
+
+ subProofRequests[i] = subProofRequest
+ }
+
+ proofBuilder, err := ursa.NewProofBuilder()
+ if err != nil {
+ return nil, err
+ }
+ err = proofBuilder.AddCommonAttribute("master_secret")
+ if err != nil {
+ return nil, err
+ }
+
+ subProofs := make([]*clapi.SubProof, len(subProofRequests))
+ for i, subProofRequest := range subProofRequests {
+ cred := credentials[i]
+ credDef := credDefs[i]
+
+ credentialValues, err := BuildValues(cred.Values, &s.masterSecretStr)
+ if err != nil {
+ return nil, err
+ }
+ defer credentialValues.Free()
+
+ schema, nonSchema, err := BuildSchema(credDef.Attrs)
+ if err != nil {
+ return nil, err
+ }
+ defer schema.Free()
+ defer nonSchema.Free()
+
+ err = proofBuilder.AddSubProofRequest(
+ subProofRequest,
+ schema,
+ nonSchema,
+ cred.Signature,
+ credentialValues,
+ credDef.CredPubKey,
+ )
+ if err != nil {
+ return nil, err
+ }
+
+ subProofs[i] = &clapi.SubProof{
+ SubProof: subProofRequest,
+ Attrs: credDef.Attrs,
+ }
+ }
+
+ ursaProof, err := proofBuilder.Finalize(presentationRequest.Nonce)
+ if err != nil {
+ return nil, err
+ }
+
+ return &clapi.Proof{
+ Proof: ursaProof,
+ SubProofs: subProofs,
+ }, nil
+}
+
+func (s *CLProver) Free() error {
+ err := s.masterSecret.Free()
+ if err != nil {
+ return err
+ }
+ return nil
+}
diff --git a/pkg/crypto/tinkcrypto/primitive/cl/subtle/cl_prover_test.go b/pkg/crypto/tinkcrypto/primitive/cl/subtle/cl_prover_test.go
new file mode 100644
index 000000000..5484cc841
--- /dev/null
+++ b/pkg/crypto/tinkcrypto/primitive/cl/subtle/cl_prover_test.go
@@ -0,0 +1,116 @@
+//go:build ursa
+// +build ursa
+
+/*
+Copyright Avast Software. All Rights Reserved.
+
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package subtle
+
+import (
+ "testing"
+
+ clapi "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/cl/api"
+ "github.com/stretchr/testify/require"
+)
+
+func TestIsCLProver(t *testing.T) {
+ clProver := NewTestCLProver(t)
+ defer clProver.Free()
+
+ _, ok := interface{}(clProver).(clapi.Prover)
+ require.True(t, ok)
+}
+
+func TestCreateCredentialRequest(t *testing.T) {
+ clProver := NewTestCLProver(t)
+ defer clProver.Free()
+ clIssuer := NewTestCLIssuer(t)
+ defer clIssuer.Free()
+
+ credDef, err := clIssuer.GetCredentialDefinition()
+ require.NoError(t, err)
+
+ credOffer, err := clIssuer.CreateCredentialOffer()
+ defer credOffer.Free()
+ require.NoError(t, err)
+
+ credReq, err := clProver.CreateCredentialRequest(credOffer, credDef, "myproverID")
+ defer credReq.Free()
+
+ require.NoError(t, err)
+ require.NotEmpty(t, credReq.Nonce)
+ require.NotEmpty(t, credReq.BlindedCredentialSecrets)
+ require.Equal(t, "myproverID", credReq.ProverId)
+}
+
+func TestProcessCredential(t *testing.T) {
+ clProver := NewTestCLProver(t)
+ defer clProver.Free()
+ clIssuer := NewTestCLIssuer(t)
+ defer clIssuer.Free()
+
+ credDef, err := clIssuer.GetCredentialDefinition()
+ require.NoError(t, err)
+
+ credOffer, err := clIssuer.CreateCredentialOffer()
+ defer credOffer.Free()
+ require.NoError(t, err)
+
+ credReq, err := clProver.CreateCredentialRequest(credOffer, credDef, "proverID")
+ defer credReq.Free()
+ require.NoError(t, err)
+
+ values := NewTestValues(t, *credOffer)
+ cred, err := clIssuer.IssueCredential(values, credReq, credOffer)
+ defer cred.Free()
+ require.NoError(t, err)
+
+ err = clProver.ProcessCredential(cred, credReq, credDef)
+ require.NoError(t, err)
+}
+
+func TestCreateProof(t *testing.T) {
+ clProver := NewTestCLProver(t)
+ defer clProver.Free()
+ clIssuer := NewTestCLIssuer(t)
+ defer clIssuer.Free()
+
+ credDef, err := clIssuer.GetCredentialDefinition()
+ require.NoError(t, err)
+
+ credOffer, err := clIssuer.CreateCredentialOffer()
+ defer credOffer.Free()
+ require.NoError(t, err)
+
+ credReq, err := clProver.CreateCredentialRequest(credOffer, credDef, "proverID")
+ defer credReq.Free()
+ require.NoError(t, err)
+
+ values := NewTestValues(t, *credOffer)
+ cred, err := clIssuer.IssueCredential(values, credReq, credOffer)
+ defer cred.Free()
+ require.NoError(t, err)
+
+ err = clProver.ProcessCredential(cred, credReq, credDef)
+ require.NoError(t, err)
+
+ presReq := NewTestPresentationRequest(t)
+ defer presReq.Free()
+
+ proof, err := clProver.CreateProof(presReq, []*clapi.Credential{cred}, []*clapi.CredentialDefinition{credDef})
+ defer proof.Free()
+
+ require.NoError(t, err)
+ require.NotEmpty(t, proof)
+ require.NotEmpty(t, proof.Proof)
+ require.NotEmpty(t, proof.SubProofs)
+ require.NotEmpty(t, proof.SubProofs[0])
+ require.NotEmpty(t, proof.SubProofs[0].Attrs)
+ require.NotEmpty(t, proof.SubProofs[0].SubProof)
+
+ err = Verify(t, presReq, proof, credDef)
+ require.NoError(t, err)
+}
diff --git a/pkg/crypto/tinkcrypto/primitive/cl/subtle/helper.go b/pkg/crypto/tinkcrypto/primitive/cl/subtle/helper.go
new file mode 100644
index 000000000..58b0fdc2b
--- /dev/null
+++ b/pkg/crypto/tinkcrypto/primitive/cl/subtle/helper.go
@@ -0,0 +1,68 @@
+//go:build ursa
+// +build ursa
+
+/*
+Copyright Avast Software. All Rights Reserved.
+
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package subtle
+
+import "github.com/hyperledger/ursa-wrapper-go/pkg/libursa/ursa"
+
+func BuildSchema(attrs []string) (*ursa.CredentialSchemaHandle, *ursa.NonCredentialSchemaHandle, error) {
+ schemaBuilder, err := ursa.NewCredentialSchemaBuilder()
+ if err != nil {
+ return nil, nil, err
+ }
+ for _, attr := range attrs {
+ err = schemaBuilder.AddAttr(attr)
+ if err != nil {
+ return nil, nil, err
+ }
+ }
+ schema, err := schemaBuilder.Finalize()
+ if err != nil {
+ return nil, nil, err
+ }
+
+ nonSchemaBuilder, err := ursa.NewNonCredentialSchemaBuilder()
+ if err != nil {
+ return nil, nil, err
+ }
+ err = nonSchemaBuilder.AddAttr("master_secret")
+ if err != nil {
+ return nil, nil, err
+ }
+ nonSchema, err := nonSchemaBuilder.Finalize()
+ if err != nil {
+ return nil, nil, err
+ }
+ return schema, nonSchema, nil
+}
+
+func BuildValues(values map[string]interface{}, masterSecretStr *string) (*ursa.CredentialValues, error) {
+ valuesBuilder, err := ursa.NewValueBuilder()
+ if err != nil {
+ return nil, err
+ }
+ if masterSecretStr != nil {
+ err = valuesBuilder.AddDecHidden("master_secret", *masterSecretStr)
+ if err != nil {
+ return nil, err
+ }
+ }
+ for k, v := range values {
+ _, enc := ursa.EncodeValue(v)
+ err = valuesBuilder.AddDecKnown(k, enc)
+ if err != nil {
+ return nil, err
+ }
+ }
+ credentialValues, err := valuesBuilder.Finalize()
+ if err != nil {
+ return nil, err
+ }
+ return credentialValues, nil
+}
diff --git a/pkg/crypto/tinkcrypto/primitive/cl/subtle/test_utils.go b/pkg/crypto/tinkcrypto/primitive/cl/subtle/test_utils.go
new file mode 100644
index 000000000..ebe0bdb4f
--- /dev/null
+++ b/pkg/crypto/tinkcrypto/primitive/cl/subtle/test_utils.go
@@ -0,0 +1,102 @@
+//go:build ursa
+// +build ursa
+
+/*
+Copyright Avast Software. All Rights Reserved.
+
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package subtle
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/require"
+
+ clapi "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/cl/api"
+ "github.com/hyperledger/ursa-wrapper-go/pkg/libursa/ursa"
+)
+
+func NewTestCLProver(t *testing.T) *CLProver {
+ prover, err := NewCLProver(CreateMasterSecretKeyJson(t))
+ require.NoError(t, err)
+ return prover
+}
+
+func NewTestCLIssuer(t *testing.T) *CLIssuer {
+ issuer, err := NewCLIssuer(CreateCredentialDefinitionJson(t))
+ require.NoError(t, err)
+ return issuer
+}
+
+func NewTestValues(t *testing.T, credOffer clapi.CredentialOffer) map[string]interface{} {
+ return map[string]interface{}{"attr1": 5, "attr2": "aaa"}
+}
+
+func NewTestPresentationRequest(t *testing.T) *clapi.PresentationRequest {
+ nonce, err := ursa.NewNonce()
+ require.NoError(t, err)
+ item := clapi.PresentationRequestItem{
+ RevealedAttrs: []string{"attr2"},
+ Predicates: []*clapi.Predicate{
+ {
+ PType: "GE",
+ Attr: "attr1",
+ Value: 4,
+ },
+ },
+ }
+ return &clapi.PresentationRequest{
+ Items: []*clapi.PresentationRequestItem{&item},
+ Nonce: nonce,
+ }
+}
+
+func CreateMasterSecretKeyJson(t *testing.T) []byte {
+ masterSecret, err := ursa.NewMasterSecret()
+ require.NoError(t, err)
+ masterSecretJson, err := masterSecret.ToJSON()
+ require.NoError(t, err)
+ return masterSecretJson
+}
+
+func CreateCredentialDefinitionJson(t *testing.T) ([]byte, []byte, []byte, []string) {
+ attrs := []string{"attr1", "attr2"}
+ schema, nonSchema, err := BuildSchema(attrs)
+ require.NoError(t, err)
+
+ credDef, err := ursa.NewCredentialDef(schema, nonSchema, false)
+
+ privKeyJson, err := credDef.PrivKey.ToJSON()
+ require.NoError(t, err)
+ pubKeyJson, err := credDef.PubKey.ToJSON()
+ require.NoError(t, err)
+ proofJson, err := credDef.KeyCorrectnessProof.ToJSON()
+ require.NoError(t, err)
+
+ require.NoError(t, err)
+ return privKeyJson, pubKeyJson, proofJson, attrs
+}
+
+func Verify(
+ t *testing.T, presentationReq *clapi.PresentationRequest, proof *clapi.Proof, credDef *clapi.CredentialDefinition,
+) error {
+ verifier, err := ursa.NewProofVerifier()
+ require.NoError(t, err)
+
+ subProof := proof.SubProofs[0]
+ schema, nonSchema, err := BuildSchema(subProof.Attrs)
+ if err != nil {
+ return err
+ }
+ defer schema.Free()
+ defer nonSchema.Free()
+
+ err = verifier.AddSubProofRequest(
+ subProof.SubProof, schema, nonSchema, credDef.CredPubKey,
+ )
+ require.NoError(t, err)
+
+ return verifier.Verify(proof.Proof, presentationReq.Nonce)
+}
diff --git a/pkg/crypto/tinkcrypto/primitive/proto/cl_go_proto/cl.pb.go b/pkg/crypto/tinkcrypto/primitive/proto/cl_go_proto/cl.pb.go
new file mode 100755
index 000000000..5ea874c5b
--- /dev/null
+++ b/pkg/crypto/tinkcrypto/primitive/proto/cl_go_proto/cl.pb.go
@@ -0,0 +1,532 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.25.0
+// protoc v3.14.0
+// source: proto/cl.proto
+
+package cl_go_proto
+
+import (
+ proto "github.com/golang/protobuf/proto"
+ _ "github.com/google/tink/go/proto/common_go_proto"
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+ reflect "reflect"
+ sync "sync"
+)
+
+const (
+ // Verify that this generated code is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+ // Verify that runtime/protoimpl is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+// This is a compile-time assertion that a sufficiently up-to-date version
+// of the legacy proto package is being used.
+const _ = proto.ProtoPackageIsVersion4
+
+type CLCredDefParams struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Attrs []string `protobuf:"bytes,1,rep,name=attrs,proto3" json:"attrs,omitempty"`
+}
+
+func (x *CLCredDefParams) Reset() {
+ *x = CLCredDefParams{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_proto_cl_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *CLCredDefParams) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CLCredDefParams) ProtoMessage() {}
+
+func (x *CLCredDefParams) ProtoReflect() protoreflect.Message {
+ mi := &file_proto_cl_proto_msgTypes[0]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use CLCredDefParams.ProtoReflect.Descriptor instead.
+func (*CLCredDefParams) Descriptor() ([]byte, []int) {
+ return file_proto_cl_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *CLCredDefParams) GetAttrs() []string {
+ if x != nil {
+ return x.Attrs
+ }
+ return nil
+}
+
+type CLCredDefPublicKey struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Version uint32 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"`
+ KeyValue []byte `protobuf:"bytes,2,opt,name=key_value,json=keyValue,proto3" json:"key_value,omitempty"`
+ KeyCorrectnessProof []byte `protobuf:"bytes,3,opt,name=key_correctness_proof,json=keyCorrectnessProof,proto3" json:"key_correctness_proof,omitempty"`
+ Params *CLCredDefParams `protobuf:"bytes,4,opt,name=params,proto3" json:"params,omitempty"`
+}
+
+func (x *CLCredDefPublicKey) Reset() {
+ *x = CLCredDefPublicKey{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_proto_cl_proto_msgTypes[1]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *CLCredDefPublicKey) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CLCredDefPublicKey) ProtoMessage() {}
+
+func (x *CLCredDefPublicKey) ProtoReflect() protoreflect.Message {
+ mi := &file_proto_cl_proto_msgTypes[1]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use CLCredDefPublicKey.ProtoReflect.Descriptor instead.
+func (*CLCredDefPublicKey) Descriptor() ([]byte, []int) {
+ return file_proto_cl_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *CLCredDefPublicKey) GetVersion() uint32 {
+ if x != nil {
+ return x.Version
+ }
+ return 0
+}
+
+func (x *CLCredDefPublicKey) GetKeyValue() []byte {
+ if x != nil {
+ return x.KeyValue
+ }
+ return nil
+}
+
+func (x *CLCredDefPublicKey) GetKeyCorrectnessProof() []byte {
+ if x != nil {
+ return x.KeyCorrectnessProof
+ }
+ return nil
+}
+
+func (x *CLCredDefPublicKey) GetParams() *CLCredDefParams {
+ if x != nil {
+ return x.Params
+ }
+ return nil
+}
+
+type CLCredDefPrivateKey struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Version uint32 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"`
+ PublicKey *CLCredDefPublicKey `protobuf:"bytes,2,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"`
+ KeyValue []byte `protobuf:"bytes,3,opt,name=key_value,json=keyValue,proto3" json:"key_value,omitempty"`
+}
+
+func (x *CLCredDefPrivateKey) Reset() {
+ *x = CLCredDefPrivateKey{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_proto_cl_proto_msgTypes[2]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *CLCredDefPrivateKey) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CLCredDefPrivateKey) ProtoMessage() {}
+
+func (x *CLCredDefPrivateKey) ProtoReflect() protoreflect.Message {
+ mi := &file_proto_cl_proto_msgTypes[2]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use CLCredDefPrivateKey.ProtoReflect.Descriptor instead.
+func (*CLCredDefPrivateKey) Descriptor() ([]byte, []int) {
+ return file_proto_cl_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *CLCredDefPrivateKey) GetVersion() uint32 {
+ if x != nil {
+ return x.Version
+ }
+ return 0
+}
+
+func (x *CLCredDefPrivateKey) GetPublicKey() *CLCredDefPublicKey {
+ if x != nil {
+ return x.PublicKey
+ }
+ return nil
+}
+
+func (x *CLCredDefPrivateKey) GetKeyValue() []byte {
+ if x != nil {
+ return x.KeyValue
+ }
+ return nil
+}
+
+type CLCredDefKeyFormat struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Params *CLCredDefParams `protobuf:"bytes,1,opt,name=params,proto3" json:"params,omitempty"`
+}
+
+func (x *CLCredDefKeyFormat) Reset() {
+ *x = CLCredDefKeyFormat{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_proto_cl_proto_msgTypes[3]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *CLCredDefKeyFormat) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CLCredDefKeyFormat) ProtoMessage() {}
+
+func (x *CLCredDefKeyFormat) ProtoReflect() protoreflect.Message {
+ mi := &file_proto_cl_proto_msgTypes[3]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use CLCredDefKeyFormat.ProtoReflect.Descriptor instead.
+func (*CLCredDefKeyFormat) Descriptor() ([]byte, []int) {
+ return file_proto_cl_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *CLCredDefKeyFormat) GetParams() *CLCredDefParams {
+ if x != nil {
+ return x.Params
+ }
+ return nil
+}
+
+type CLMasterSecret struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Version uint32 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"`
+ KeyValue []byte `protobuf:"bytes,2,opt,name=key_value,json=keyValue,proto3" json:"key_value,omitempty"`
+}
+
+func (x *CLMasterSecret) Reset() {
+ *x = CLMasterSecret{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_proto_cl_proto_msgTypes[4]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *CLMasterSecret) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CLMasterSecret) ProtoMessage() {}
+
+func (x *CLMasterSecret) ProtoReflect() protoreflect.Message {
+ mi := &file_proto_cl_proto_msgTypes[4]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use CLMasterSecret.ProtoReflect.Descriptor instead.
+func (*CLMasterSecret) Descriptor() ([]byte, []int) {
+ return file_proto_cl_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *CLMasterSecret) GetVersion() uint32 {
+ if x != nil {
+ return x.Version
+ }
+ return 0
+}
+
+func (x *CLMasterSecret) GetKeyValue() []byte {
+ if x != nil {
+ return x.KeyValue
+ }
+ return nil
+}
+
+type CLMasterSecretKeyFormat struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+}
+
+func (x *CLMasterSecretKeyFormat) Reset() {
+ *x = CLMasterSecretKeyFormat{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_proto_cl_proto_msgTypes[5]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *CLMasterSecretKeyFormat) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CLMasterSecretKeyFormat) ProtoMessage() {}
+
+func (x *CLMasterSecretKeyFormat) ProtoReflect() protoreflect.Message {
+ mi := &file_proto_cl_proto_msgTypes[5]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use CLMasterSecretKeyFormat.ProtoReflect.Descriptor instead.
+func (*CLMasterSecretKeyFormat) Descriptor() ([]byte, []int) {
+ return file_proto_cl_proto_rawDescGZIP(), []int{5}
+}
+
+var File_proto_cl_proto protoreflect.FileDescriptor
+
+var file_proto_cl_proto_rawDesc = []byte{
+ 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+ 0x12, 0x12, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2e,
+ 0x74, 0x69, 0x6e, 0x6b, 0x1a, 0x12, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6f, 0x6d, 0x6d,
+ 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x27, 0x0a, 0x0f, 0x43, 0x4c, 0x43, 0x72,
+ 0x65, 0x64, 0x44, 0x65, 0x66, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x61,
+ 0x74, 0x74, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x61, 0x74, 0x74, 0x72,
+ 0x73, 0x22, 0xbc, 0x01, 0x0a, 0x12, 0x43, 0x4c, 0x43, 0x72, 0x65, 0x64, 0x44, 0x65, 0x66, 0x50,
+ 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73,
+ 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69,
+ 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x6b, 0x65, 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
+ 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12,
+ 0x32, 0x0a, 0x15, 0x6b, 0x65, 0x79, 0x5f, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x6e, 0x65,
+ 0x73, 0x73, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x13,
+ 0x6b, 0x65, 0x79, 0x43, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x6e, 0x65, 0x73, 0x73, 0x50, 0x72,
+ 0x6f, 0x6f, 0x66, 0x12, 0x3b, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x04, 0x20,
+ 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x72, 0x79,
+ 0x70, 0x74, 0x6f, 0x2e, 0x74, 0x69, 0x6e, 0x6b, 0x2e, 0x43, 0x4c, 0x43, 0x72, 0x65, 0x64, 0x44,
+ 0x65, 0x66, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73,
+ 0x22, 0x93, 0x01, 0x0a, 0x13, 0x43, 0x4c, 0x43, 0x72, 0x65, 0x64, 0x44, 0x65, 0x66, 0x50, 0x72,
+ 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73,
+ 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69,
+ 0x6f, 0x6e, 0x12, 0x45, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79,
+ 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
+ 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2e, 0x74, 0x69, 0x6e, 0x6b, 0x2e, 0x43, 0x4c, 0x43, 0x72,
+ 0x65, 0x64, 0x44, 0x65, 0x66, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x09,
+ 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x6b, 0x65, 0x79,
+ 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x6b, 0x65,
+ 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x51, 0x0a, 0x12, 0x43, 0x4c, 0x43, 0x72, 0x65, 0x64,
+ 0x44, 0x65, 0x66, 0x4b, 0x65, 0x79, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x3b, 0x0a, 0x06,
+ 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x67,
+ 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2e, 0x74, 0x69, 0x6e,
+ 0x6b, 0x2e, 0x43, 0x4c, 0x43, 0x72, 0x65, 0x64, 0x44, 0x65, 0x66, 0x50, 0x61, 0x72, 0x61, 0x6d,
+ 0x73, 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0x47, 0x0a, 0x0e, 0x43, 0x4c, 0x4d,
+ 0x61, 0x73, 0x74, 0x65, 0x72, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x76,
+ 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x76, 0x65,
+ 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x6b, 0x65, 0x79, 0x5f, 0x76, 0x61, 0x6c,
+ 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x56, 0x61, 0x6c,
+ 0x75, 0x65, 0x22, 0x19, 0x0a, 0x17, 0x43, 0x4c, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x53, 0x65,
+ 0x63, 0x72, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x42, 0x86, 0x01,
+ 0x0a, 0x1c, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x72, 0x79,
+ 0x70, 0x74, 0x6f, 0x2e, 0x74, 0x69, 0x6e, 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01,
+ 0x5a, 0x5b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x79, 0x70,
+ 0x65, 0x72, 0x6c, 0x65, 0x64, 0x67, 0x65, 0x72, 0x2f, 0x61, 0x72, 0x69, 0x65, 0x73, 0x2d, 0x66,
+ 0x72, 0x61, 0x6d, 0x65, 0x77, 0x6f, 0x72, 0x6b, 0x2d, 0x67, 0x6f, 0x2f, 0x70, 0x6b, 0x67, 0x2f,
+ 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2f, 0x74, 0x69, 0x6e, 0x6b, 0x63, 0x72, 0x79, 0x70, 0x74,
+ 0x6f, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x2f, 0x63, 0x6c, 0x5f, 0x67, 0x6f, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0xa2, 0x02, 0x06,
+ 0x54, 0x49, 0x4e, 0x4b, 0x50, 0x42, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+ file_proto_cl_proto_rawDescOnce sync.Once
+ file_proto_cl_proto_rawDescData = file_proto_cl_proto_rawDesc
+)
+
+func file_proto_cl_proto_rawDescGZIP() []byte {
+ file_proto_cl_proto_rawDescOnce.Do(func() {
+ file_proto_cl_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_cl_proto_rawDescData)
+ })
+ return file_proto_cl_proto_rawDescData
+}
+
+var file_proto_cl_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
+var file_proto_cl_proto_goTypes = []interface{}{
+ (*CLCredDefParams)(nil), // 0: google.crypto.tink.CLCredDefParams
+ (*CLCredDefPublicKey)(nil), // 1: google.crypto.tink.CLCredDefPublicKey
+ (*CLCredDefPrivateKey)(nil), // 2: google.crypto.tink.CLCredDefPrivateKey
+ (*CLCredDefKeyFormat)(nil), // 3: google.crypto.tink.CLCredDefKeyFormat
+ (*CLMasterSecret)(nil), // 4: google.crypto.tink.CLMasterSecret
+ (*CLMasterSecretKeyFormat)(nil), // 5: google.crypto.tink.CLMasterSecretKeyFormat
+}
+var file_proto_cl_proto_depIdxs = []int32{
+ 0, // 0: google.crypto.tink.CLCredDefPublicKey.params:type_name -> google.crypto.tink.CLCredDefParams
+ 1, // 1: google.crypto.tink.CLCredDefPrivateKey.public_key:type_name -> google.crypto.tink.CLCredDefPublicKey
+ 0, // 2: google.crypto.tink.CLCredDefKeyFormat.params:type_name -> google.crypto.tink.CLCredDefParams
+ 3, // [3:3] is the sub-list for method output_type
+ 3, // [3:3] is the sub-list for method input_type
+ 3, // [3:3] is the sub-list for extension type_name
+ 3, // [3:3] is the sub-list for extension extendee
+ 0, // [0:3] is the sub-list for field type_name
+}
+
+func init() { file_proto_cl_proto_init() }
+func file_proto_cl_proto_init() {
+ if File_proto_cl_proto != nil {
+ return
+ }
+ if !protoimpl.UnsafeEnabled {
+ file_proto_cl_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*CLCredDefParams); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_proto_cl_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*CLCredDefPublicKey); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_proto_cl_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*CLCredDefPrivateKey); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_proto_cl_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*CLCredDefKeyFormat); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_proto_cl_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*CLMasterSecret); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_proto_cl_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*CLMasterSecretKeyFormat); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ }
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor: file_proto_cl_proto_rawDesc,
+ NumEnums: 0,
+ NumMessages: 6,
+ NumExtensions: 0,
+ NumServices: 0,
+ },
+ GoTypes: file_proto_cl_proto_goTypes,
+ DependencyIndexes: file_proto_cl_proto_depIdxs,
+ MessageInfos: file_proto_cl_proto_msgTypes,
+ }.Build()
+ File_proto_cl_proto = out.File
+ file_proto_cl_proto_rawDesc = nil
+ file_proto_cl_proto_goTypes = nil
+ file_proto_cl_proto_depIdxs = nil
+}
diff --git a/proto/tink/cl.proto b/proto/tink/cl.proto
new file mode 100644
index 000000000..656cb5995
--- /dev/null
+++ b/proto/tink/cl.proto
@@ -0,0 +1,50 @@
+/*
+Copyright SecureKey Technologies Inc. All Rights Reserved.
+
+SPDX-License-Identifier: Apache-2.0
+*/
+
+// Definitions for BBS+.
+syntax = "proto3";
+
+package google.crypto.tink;
+import "proto/common.proto";
+
+option java_package = "com.google.crypto.tink.proto";
+option java_multiple_files = true;
+option objc_class_prefix = "TINKPB";
+option go_package = "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/cl_go_proto";
+
+// Protos CL Credential Definition keys
+
+// Parameters of CL Cred Def keys.
+message CLCredDefParams {
+ repeated string attrs = 1;
+}
+
+// Cred Def Public Key
+message CLCredDefPublicKey {
+ uint32 version = 1;
+ bytes key_value = 2; // json marshalled CL Cred Def public key value.
+ bytes key_correctness_proof = 3; // json marshalled CL Cred Def correctness proof value.
+ CLCredDefParams params = 4;
+}
+
+// Cred Def Private Key
+message CLCredDefPrivateKey {
+ uint32 version = 1;
+ CLCredDefPublicKey public_key = 2;
+ bytes key_value = 3; // json marshalled CL Cred Def private key value.
+}
+
+message CLCredDefKeyFormat {
+ CLCredDefParams params = 1;
+}
+
+message CLMasterSecret {
+ uint32 version = 1;
+ bytes key_value = 2;
+}
+
+message CLMasterSecretKeyFormat {
+}
\ No newline at end of file
diff --git a/scripts/check_unit_ursa.sh b/scripts/check_unit_ursa.sh
new file mode 100755
index 000000000..560ba6808
--- /dev/null
+++ b/scripts/check_unit_ursa.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+#
+# Copyright Avast Software. All Rights Reserved.
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+set -e
+
+echo "Running $0"
+
+go generate ./...
+
+# TODO Support collecting code coverage
+# TODO Create containers with libursa installed for local tests and development.
+# Current CI uses ghcr.io/hyperledger/ursa-wrapper-go/uwg-build.
+
+ # Running aries-framework-go unit test with ursa
+PKGS=$(go list -tags ursa github.com/hyperledger/aries-framework-go/pkg/... 2> /dev/null | grep -v /mocks | grep -v /aries-js-worker)
+go test -tags ursa $PKGS -count=1 -race -timeout=10m
diff --git a/test/bdd/go.sum b/test/bdd/go.sum
index 894418714..a8b63d9d4 100644
--- a/test/bdd/go.sum
+++ b/test/bdd/go.sum
@@ -280,6 +280,8 @@ github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKe
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220606124520-53422361c38c/go.mod h1:JrwivOOQmuXbV1mFWgBGWnfCorOFdfGkpBsYK8dYrfM=
+github.com/hyperledger/ursa-wrapper-go v0.3.0 h1:ZYgPkPqy0AWEoU2Dhiziz91QacNdIX3j21UIOIVCXA8=
+github.com/hyperledger/ursa-wrapper-go v0.3.0/go.mod h1:nPSAuMasIzSVciQo22PedBk4Opph6bJ6ia3ms7BH/mk=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
From d96b693387a76b5b26ade1c658ff2876b8c11d35 Mon Sep 17 00:00:00 2001
From: Chris Abernethy
Date: Thu, 14 Jul 2022 18:05:20 -0400
Subject: [PATCH 53/54] feat: add did document support for alsoKnownAs (#3277)
---
pkg/doc/did/doc.go | 23 +++-
pkg/doc/did/doc_test.go | 124 ++++++++++++++++--
pkg/doc/did/schema.go | 24 ++++
pkg/doc/did/testdata/valid_doc.jsonld | 3 +
.../did/testdata/valid_doc_resolution.jsonld | 3 +
pkg/doc/did/testdata/valid_doc_v0.11.jsonld | 3 +
.../did/testdata/valid_doc_with_base.jsonld | 3 +
7 files changed, 168 insertions(+), 15 deletions(-)
diff --git a/pkg/doc/did/doc.go b/pkg/doc/did/doc.go
index 69f7c8cd6..1b7d5b46f 100644
--- a/pkg/doc/did/doc.go
+++ b/pkg/doc/did/doc.go
@@ -263,6 +263,7 @@ func ParseDocumentResolution(data []byte) (*DocResolution, error) {
type Doc struct {
Context []string
ID string
+ AlsoKnownAs []string
VerificationMethod []VerificationMethod
Service []Service
Authentication []Verification
@@ -428,6 +429,7 @@ func NewReferencedVerification(vm *VerificationMethod, r VerificationRelationshi
type rawDoc struct {
Context interface{} `json:"@context,omitempty"`
ID string `json:"id,omitempty"`
+ AlsoKnownAs []interface{} `json:"alsoKnownAs,omitempty"`
VerificationMethod []map[string]interface{} `json:"verificationMethod,omitempty"`
PublicKey []map[string]interface{} `json:"publicKey,omitempty"`
Service []map[string]interface{} `json:"service,omitempty"`
@@ -489,9 +491,10 @@ func ParseDocument(data []byte) (*Doc, error) {
}
doc := &Doc{
- ID: raw.ID,
- Created: raw.Created,
- Updated: raw.Updated,
+ ID: raw.ID,
+ AlsoKnownAs: stringArray(raw.AlsoKnownAs),
+ Created: raw.Created,
+ Updated: raw.Updated,
}
context, baseURI := parseContext(raw.Context)
@@ -1114,6 +1117,8 @@ func (doc *Doc) JSONBytes() ([]byte, error) {
context = doc.Context[0]
}
+ aka := populateRawAlsoKnownAs(doc.AlsoKnownAs)
+
vm, err := populateRawVM(context, doc.ID, doc.processingMeta.baseURI, doc.VerificationMethod)
if err != nil {
return nil, fmt.Errorf("JSON unmarshalling of Verification Method failed: %w", err)
@@ -1148,7 +1153,7 @@ func (doc *Doc) JSONBytes() ([]byte, error) {
}
raw := &rawDoc{
- Context: doc.Context, ID: doc.ID, VerificationMethod: vm,
+ Context: doc.Context, ID: doc.ID, AlsoKnownAs: aka, VerificationMethod: vm,
Authentication: auths, AssertionMethod: assertionMethods, CapabilityDelegation: capabilityDelegations,
CapabilityInvocation: capabilityInvocations, KeyAgreement: keyAgreements,
Service: populateRawServices(doc.Service, doc.ID, doc.processingMeta.baseURI), Created: doc.Created,
@@ -1395,6 +1400,16 @@ func populateRawServices(services []Service, didID, baseURI string) []map[string
return rawServices
}
+func populateRawAlsoKnownAs(aka []string) []interface{} {
+ rawAka := make([]interface{}, len(aka))
+
+ for i, v := range aka {
+ rawAka[i] = v
+ }
+
+ return rawAka
+}
+
func populateRawVM(context, didID, baseURI string, pks []VerificationMethod) ([]map[string]interface{}, error) {
var rawVM []map[string]interface{}
diff --git a/pkg/doc/did/doc_test.go b/pkg/doc/did/doc_test.go
index 2a30f0127..e73379033 100644
--- a/pkg/doc/did/doc_test.go
+++ b/pkg/doc/did/doc_test.go
@@ -89,6 +89,10 @@ func TestValidWithDocBase(t *testing.T) {
// test doc id
require.Equal(t, doc.ID, "did:example:123456789abcdefghi")
+ // test alsoKnownAs
+ require.Equal(t, 1, len(doc.AlsoKnownAs))
+ require.Equal(t, "did:example:123", doc.AlsoKnownAs[0])
+
hexDecodeValue, err := hex.DecodeString("02b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71")
block, _ := pem.Decode([]byte(pemPK))
require.NotNil(t, block)
@@ -175,6 +179,8 @@ func TestDocResolution(t *testing.T) {
require.Equal(t, 1, len(d.Context))
require.Equal(t, "https://w3id.org/did-resolution/v1", d.Context[0])
require.Equal(t, "did:example:21tDAKCERh95uGgKbJNHYp", d.DIDDocument.ID)
+ require.Equal(t, 1, len(d.DIDDocument.AlsoKnownAs))
+ require.Equal(t, "did:example:123", d.DIDDocument.AlsoKnownAs[0])
require.Equal(t, true, d.DocumentMetadata.Method.Published)
require.Equal(t, "did:ex:123333", d.DocumentMetadata.CanonicalID)
@@ -187,6 +193,8 @@ func TestDocResolution(t *testing.T) {
require.Equal(t, 1, len(d.Context))
require.Equal(t, "https://w3id.org/did-resolution/v1", d.Context[0])
require.Equal(t, "did:example:21tDAKCERh95uGgKbJNHYp", d.DIDDocument.ID)
+ require.Equal(t, 1, len(d.DIDDocument.AlsoKnownAs))
+ require.Equal(t, "did:example:123", d.DIDDocument.AlsoKnownAs[0])
require.Equal(t, true, d.DocumentMetadata.Method.Published)
require.Equal(t, "did:ex:123333", d.DocumentMetadata.CanonicalID)
})
@@ -209,6 +217,10 @@ func TestValid(t *testing.T) {
// test doc id
require.Equal(t, doc.ID, "did:example:21tDAKCERh95uGgKbJNHYp")
+ // test alsoKnownAs
+ require.Equal(t, 1, len(doc.AlsoKnownAs))
+ require.Equal(t, "did:example:123", doc.AlsoKnownAs[0])
+
hexDecodeValue, err := hex.DecodeString("02b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71")
block, _ := pem.Decode([]byte(pemPK))
require.NotNil(t, block)
@@ -561,6 +573,96 @@ func TestValidateDidDocID(t *testing.T) {
})
}
+func TestValidateDidDocAlsoKnownAs(t *testing.T) {
+ t.Run("test did doc with duplicate alsoKnownAs entries", func(t *testing.T) {
+ docs := []string{validDoc, validDocV011}
+ for _, d := range docs {
+ raw := &rawDoc{}
+ require.NoError(t, json.Unmarshal([]byte(d), &raw))
+ raw.AlsoKnownAs = []interface{}{"did:example:123", "did:example:123"}
+ bytes, err := json.Marshal(raw)
+ require.NoError(t, err)
+ err = validate(bytes, raw.schemaLoader())
+ require.Error(t, err)
+ require.Contains(t, err.Error(), "must be unique")
+ }
+ })
+
+ t.Run("test did doc with non-uri alsoKnownAs string", func(t *testing.T) {
+ docs := []string{validDoc, validDocV011}
+ for _, d := range docs {
+ raw := &rawDoc{}
+ require.NoError(t, json.Unmarshal([]byte(d), &raw))
+ raw.AlsoKnownAs = []interface{}{"not.a.valid.uri"}
+ bytes, err := json.Marshal(raw)
+ require.NoError(t, err)
+ err = validate(bytes, raw.schemaLoader())
+ require.Error(t, err)
+ require.Contains(t, err.Error(), "Does not match format 'uri'")
+ }
+ })
+
+ t.Run("test did doc with non-string alsoKnownAs entry", func(t *testing.T) {
+ docs := []string{validDoc, validDocV011}
+ for _, d := range docs {
+ raw := &rawDoc{}
+ require.NoError(t, json.Unmarshal([]byte(d), &raw))
+ raw.AlsoKnownAs = []interface{}{0}
+ bytes, err := json.Marshal(raw)
+ require.NoError(t, err)
+ err = validate(bytes, raw.schemaLoader())
+ require.Error(t, err)
+ require.Contains(t, err.Error(), "Invalid type. Expected: string")
+ }
+ })
+
+ t.Run("test did doc with empty alsoKnownAs", func(t *testing.T) {
+ docs := []string{validDoc, validDocV011}
+ for _, d := range docs {
+ raw := &rawDoc{}
+ require.NoError(t, json.Unmarshal([]byte(d), &raw))
+ raw.AlsoKnownAs = nil
+ bytes, err := json.Marshal(raw)
+ require.NoError(t, err)
+ err = validate(bytes, raw.schemaLoader())
+ require.NoError(t, err)
+ }
+ })
+
+ t.Run("test did doc with zero-length alsoKnownAs", func(t *testing.T) {
+ docs := []string{validDoc, validDocV011}
+ for _, d := range docs {
+ raw := &rawDoc{}
+ require.NoError(t, json.Unmarshal([]byte(d), &raw))
+ raw.AlsoKnownAs = []interface{}{}
+ bytes, err := json.Marshal(raw)
+ require.NoError(t, err)
+ err = validate(bytes, raw.schemaLoader())
+ require.NoError(t, err)
+ }
+ })
+
+ t.Run("test did doc with valid alsoKnownAs entries", func(t *testing.T) {
+ docs := []string{validDoc, validDocV011}
+ valid := []interface{}{
+ "did:example:123",
+ "https://social.example/username",
+ "urn:uuid:1231",
+ }
+ for _, d := range docs {
+ for _, aka := range valid {
+ raw := &rawDoc{}
+ require.NoError(t, json.Unmarshal([]byte(d), &raw))
+ raw.AlsoKnownAs = []interface{}{aka}
+ bytes, err := json.Marshal(raw)
+ require.NoError(t, err)
+ err = validate(bytes, raw.schemaLoader())
+ require.NoError(t, err)
+ }
+ }
+ })
+}
+
func TestValidateDidDocPublicKey(t *testing.T) {
t.Run("test did doc with empty public key", func(t *testing.T) {
docs := []string{validDoc, validDocV011}
@@ -1498,20 +1600,20 @@ func TestDIDSchemas(t *testing.T) {
didStr: `{
"@context": "https://w3id.org/did/v0.11",
"id": "did:w123:world",
- "assertionMethod": ["did:w123:world#z6MksHh7qHWvybLg5QTPPdG2DgEjjduBDArV9EF9mRiRzMBN",
- "did:w123:world#_Qq0UL2Fq651Q0Fjd6TvnYE-faHiOpRlPVQcY_-tA4A",
- "did:w123:world#_TKzHv2jFIyvdTGF1Dsgwngfdg3SH6TpDv0Ta1aOEkw",
+ "assertionMethod": ["did:w123:world#z6MksHh7qHWvybLg5QTPPdG2DgEjjduBDArV9EF9mRiRzMBN",
+ "did:w123:world#_Qq0UL2Fq651Q0Fjd6TvnYE-faHiOpRlPVQcY_-tA4A",
+ "did:w123:world#_TKzHv2jFIyvdTGF1Dsgwngfdg3SH6TpDv0Ta1aOEkw",
"did:w123:world#NjQ6Y_ZMj6IUK_XkgCDwtKHlNTUTVjEYOWZtxhp1n-E"],
- "authentication": ["did:w123:world#z6MksHh7qHWvybLg5QTPPdG2DgEjjduBDArV9EF9mRiRzMBN", "",
- "did:w123:world#_TKzHv2jFIyvdTGF1Dsgwngfdg3SH6TpDv0Ta1aOEkw",
+ "authentication": ["did:w123:world#z6MksHh7qHWvybLg5QTPPdG2DgEjjduBDArV9EF9mRiRzMBN", "",
+ "did:w123:world#_TKzHv2jFIyvdTGF1Dsgwngfdg3SH6TpDv0Ta1aOEkw",
"did:w123:world#NjQ6Y_ZMj6IUK_XkgCDwtKHlNTUTVjEYOWZtxhp1n-E"],
- "capabilityDelegation": ["did:w123:world#z6MksHh7qHWvybLg5QTPPdG2DgEjjduBDArV9EF9mRiRzMBN",
- "did:w123:world#_Qq0UL2Fq651Q0Fjd6TvnYE-faHiOpRlPVQcY_-tA4A",
- "did:w123:world#_TKzHv2jFIyvdTGF1Dsgwngfdg3SH6TpDv0Ta1aOEkw",
+ "capabilityDelegation": ["did:w123:world#z6MksHh7qHWvybLg5QTPPdG2DgEjjduBDArV9EF9mRiRzMBN",
+ "did:w123:world#_Qq0UL2Fq651Q0Fjd6TvnYE-faHiOpRlPVQcY_-tA4A",
+ "did:w123:world#_TKzHv2jFIyvdTGF1Dsgwngfdg3SH6TpDv0Ta1aOEkw",
"did:w123:world#NjQ6Y_ZMj6IUK_XkgCDwtKHlNTUTVjEYOWZtxhp1n-E"],
- "capabilityInvocation": ["did:w123:world#z6MksHh7qHWvybLg5QTPPdG2DgEjjduBDArV9EF9mRiRzMBN",
- "did:w123:world#_Qq0UL2Fq651Q0Fjd6TvnYE-faHiOpRlPVQcY_-tA4A",
- "did:w123:world#_TKzHv2jFIyvdTGF1Dsgwngfdg3SH6TpDv0Ta1aOEkw",
+ "capabilityInvocation": ["did:w123:world#z6MksHh7qHWvybLg5QTPPdG2DgEjjduBDArV9EF9mRiRzMBN",
+ "did:w123:world#_Qq0UL2Fq651Q0Fjd6TvnYE-faHiOpRlPVQcY_-tA4A",
+ "did:w123:world#_TKzHv2jFIyvdTGF1Dsgwngfdg3SH6TpDv0Ta1aOEkw",
"did:w123:world#NjQ6Y_ZMj6IUK_XkgCDwtKHlNTUTVjEYOWZtxhp1n-E"],
"keyAgreement": [{
"id": "did:w123:world#zC5iai1sL93gQxn8LKh1i42fTbpfar65dVx4NYznYfG3Y5",
diff --git a/pkg/doc/did/schema.go b/pkg/doc/did/schema.go
index 10a6c298c..ca7b0de90 100644
--- a/pkg/doc/did/schema.go
+++ b/pkg/doc/did/schema.go
@@ -44,6 +44,14 @@ const (
"id": {
"type": "string"
},
+ "alsoKnownAs": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "format": "uri"
+ },
+ "uniqueItems": true
+ },
"publicKey": {
"type": "array",
"items": {
@@ -219,6 +227,14 @@ const (
"id": {
"type": "string"
},
+ "alsoKnownAs": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "format": "uri"
+ },
+ "uniqueItems": true
+ },
"publicKey": {
"type": "array",
"items": {
@@ -406,6 +422,14 @@ const (
"id": {
"type": "string"
},
+ "alsoKnownAs": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "format": "uri"
+ },
+ "uniqueItems": true
+ },
"publicKey": {
"type": "array",
"items": {
diff --git a/pkg/doc/did/testdata/valid_doc.jsonld b/pkg/doc/did/testdata/valid_doc.jsonld
index 26ca510b0..3b35c5dae 100644
--- a/pkg/doc/did/testdata/valid_doc.jsonld
+++ b/pkg/doc/did/testdata/valid_doc.jsonld
@@ -1,6 +1,9 @@
{
"@context": ["https://www.w3.org/ns/did/v1"],
"id": "did:example:21tDAKCERh95uGgKbJNHYp",
+ "alsoKnownAs": [
+ "did:example:123"
+ ],
"verificationMethod": [
{
"id": "did:example:123456789abcdefghi#keys-1",
diff --git a/pkg/doc/did/testdata/valid_doc_resolution.jsonld b/pkg/doc/did/testdata/valid_doc_resolution.jsonld
index 20a0656a1..45e28491c 100644
--- a/pkg/doc/did/testdata/valid_doc_resolution.jsonld
+++ b/pkg/doc/did/testdata/valid_doc_resolution.jsonld
@@ -5,6 +5,9 @@
"https://w3id.org/did/v1"
],
"id": "did:example:21tDAKCERh95uGgKbJNHYp",
+ "alsoKnownAs": [
+ "did:example:123"
+ ],
"verificationMethod": [
{
"id": "did:example:123456789abcdefghi#keys-1",
diff --git a/pkg/doc/did/testdata/valid_doc_v0.11.jsonld b/pkg/doc/did/testdata/valid_doc_v0.11.jsonld
index e9b46214b..e3734001e 100644
--- a/pkg/doc/did/testdata/valid_doc_v0.11.jsonld
+++ b/pkg/doc/did/testdata/valid_doc_v0.11.jsonld
@@ -1,6 +1,9 @@
{
"@context": ["https://w3id.org/did/v0.11"],
"id": "did:example:21tDAKCERh95uGgKbJNHYp",
+ "alsoKnownAs": [
+ "did:example:123"
+ ],
"publicKey": [
{
"id": "did:example:123456789abcdefghi#keys-1",
diff --git a/pkg/doc/did/testdata/valid_doc_with_base.jsonld b/pkg/doc/did/testdata/valid_doc_with_base.jsonld
index a2c73b344..bf6f8662c 100644
--- a/pkg/doc/did/testdata/valid_doc_with_base.jsonld
+++ b/pkg/doc/did/testdata/valid_doc_with_base.jsonld
@@ -2,6 +2,9 @@
"@context": ["https://www.w3.org/ns/did/v1",
{ "@base": "did:example:123456789abcdefghi"}],
"id": "did:example:123456789abcdefghi",
+ "alsoKnownAs": [
+ "did:example:123"
+ ],
"verificationMethod": [
{
"id": "#keys-1",
From cea4427c93a6c0bed602c253f5e577448c4f88df Mon Sep 17 00:00:00 2001
From: Abdulbois <30406506+Abdulbois@users.noreply.github.com>
Date: Mon, 18 Jul 2022 19:12:13 +0500
Subject: [PATCH 54/54] refactor: enable usage of legacy Anoncrypt packer. Make
nested forwards while creating forward message. Add legacyForward model
(#3272)
* refactor: remote cryptobox URLs renamed to /wrap and /unwrap (#3259)
this change updates the remote CryptoBox api URIs to point to remote KMS's key /wrap and /unwrap to match ECDH-ES and ECDH-1PU key wrapping.
This change requires the KMS server to udpate /easy to /wrap, /easyOpen and /sealOpen to /unwrap
Signed-off-by: Baha Shaaban
Signed-off-by: Abdulbois
* refactor: re enable remote kms bdd-tests with unwrapKey (#3263)
This change updates the webkms server in bdd tests and re enables commented out webkms tests requiring cryptobox's /wrap and /unwrap operations.
closes #3262
Signed-off-by: Baha Shaaban
Signed-off-by: Abdulbois
* refactor: Enable usage of legacy Anoncrypt packer. Make nested forwards while creating forward message. Add legacyForward model
- Add legacy Anoncrypt packer while creating packers
- Add ability to create nested packed forwards (one nested forward for each routing key)
- Check and convert msg field of Forward to Envelope in order to support DIDComm V1 Forward types
- Revert part of 04bfea80427b3d2ae374ddad2ced84b77c70a179 commit related to generating keys inside mediator service. Because with previous changes (having two types of generated keys belonging to the same router) it breaks Route Coordination protocol (while creating nested forwards it will pack two times to the same mediator then mediator cannot handle second forward message)
Signed-off-by: Abdulbois
* refactor: Remove test due to forcing anoncrypt while calling createForwardMessage. Fix lint errors
Signed-off-by: Abdulbois
Co-authored-by: Baha <29608896+Baha-sk@users.noreply.github.com>
---
cmd/aries-agent-mobile/go.sum | 3 +
cmd/aries-agent-rest/go.sum | 3 +
go.mod | 1 +
go.sum | 3 +
pkg/didcomm/dispatcher/outbound/outbound.go | 97 ++++++++++++++-----
.../dispatcher/outbound/outbound_test.go | 70 ++++++++-----
pkg/didcomm/packager/packager.go | 36 ++++---
pkg/didcomm/protocol/mediator/service.go | 45 +++++----
pkg/framework/aries/default.go | 11 ++-
test/bdd/go.mod | 1 +
test/bdd/go.sum | 3 +
11 files changed, 184 insertions(+), 89 deletions(-)
diff --git a/cmd/aries-agent-mobile/go.sum b/cmd/aries-agent-mobile/go.sum
index 3ccf7ba68..a991bcc5b 100644
--- a/cmd/aries-agent-mobile/go.sum
+++ b/cmd/aries-agent-mobile/go.sum
@@ -275,11 +275,14 @@ github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2
github.com/square/go-jose/v3 v3.0.0-20200630053402-0a67ce9b0693 h1:wD1IWQwAhdWclCwaf6DdzgCAe9Bfz1M+4AHRd7N786Y=
github.com/square/go-jose/v3 v3.0.0-20200630053402-0a67ce9b0693/go.mod h1:6hSY48PjDm4UObWmGLyJE9DxYVKTgR9kbCspXXJEhcU=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s=
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
github.com/teserakt-io/golang-ed25519 v0.0.0-20210104091850-3888c087a4c8 h1:RBkacARv7qY5laaXGlF4wFB/tk5rnthhPb8oIBGoagY=
diff --git a/cmd/aries-agent-rest/go.sum b/cmd/aries-agent-rest/go.sum
index cee276d49..1a7d6672b 100644
--- a/cmd/aries-agent-rest/go.sum
+++ b/cmd/aries-agent-rest/go.sum
@@ -347,11 +347,14 @@ github.com/square/go-jose/v3 v3.0.0-20200630053402-0a67ce9b0693 h1:wD1IWQwAhdWcl
github.com/square/go-jose/v3 v3.0.0-20200630053402-0a67ce9b0693/go.mod h1:6hSY48PjDm4UObWmGLyJE9DxYVKTgR9kbCspXXJEhcU=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s=
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
diff --git a/go.mod b/go.mod
index c6947f169..a45defe65 100644
--- a/go.mod
+++ b/go.mod
@@ -56,6 +56,7 @@ require (
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/pquerna/cachecontrol v0.1.0 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
+ github.com/stretchr/objx v0.4.0 // indirect
github.com/tidwall/match v1.0.3 // indirect
github.com/tidwall/pretty v1.0.2 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
diff --git a/go.sum b/go.sum
index 8ba2fa5de..b614729f7 100644
--- a/go.sum
+++ b/go.sum
@@ -322,11 +322,14 @@ github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2
github.com/square/go-jose/v3 v3.0.0-20200630053402-0a67ce9b0693 h1:wD1IWQwAhdWclCwaf6DdzgCAe9Bfz1M+4AHRd7N786Y=
github.com/square/go-jose/v3 v3.0.0-20200630053402-0a67ce9b0693/go.mod h1:6hSY48PjDm4UObWmGLyJE9DxYVKTgR9kbCspXXJEhcU=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s=
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
github.com/teserakt-io/golang-ed25519 v0.0.0-20200315192543-8255be791ce4/go.mod h1:9PdLyPiZIiW3UopXyRnPYyjUXSpiQNHRLu8fOsR3o8M=
diff --git a/pkg/didcomm/dispatcher/outbound/outbound.go b/pkg/didcomm/dispatcher/outbound/outbound.go
index 8240957db..9cc60a667 100644
--- a/pkg/didcomm/dispatcher/outbound/outbound.go
+++ b/pkg/didcomm/dispatcher/outbound/outbound.go
@@ -24,7 +24,6 @@ import (
"github.com/hyperledger/aries-framework-go/pkg/framework/aries/api/vdr"
"github.com/hyperledger/aries-framework-go/pkg/kms"
"github.com/hyperledger/aries-framework-go/pkg/store/connection"
- "github.com/hyperledger/aries-framework-go/pkg/vdr/fingerprint"
"github.com/hyperledger/aries-framework-go/spi/storage"
)
@@ -66,6 +65,15 @@ type Dispatcher struct {
didcommV2Handler *middleware.DIDCommMessageMiddleware
}
+// legacyForward is DIDComm V1 route Forward msg as declared in
+// https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0094-cross-domain-messaging/README.md
+type legacyForward struct {
+ Type string `json:"@type,omitempty"`
+ ID string `json:"@id,omitempty"`
+ To string `json:"to,omitempty"`
+ Msg *model.Envelope `json:"msg,omitempty"`
+}
+
var logger = log.New("aries-framework/didcomm/dispatcher")
// NewOutbound return new dispatcher outbound instance.
@@ -340,15 +348,12 @@ func (o *Dispatcher) Forward(msg interface{}, des *service.Destination) error {
return fmt.Errorf("outboundDispatcher.Forward: no transport found for serviceEndpoint: %s", uri)
}
-//nolint:funlen
func (o *Dispatcher) createForwardMessage(msg []byte, des *service.Destination) ([]byte, error) {
- forwardMsgType := service.ForwardMsgType
-
mtProfile := o.mediaTypeProfile(des)
var (
- senderKey []byte
- err error
+ forwardMsgType string
+ err error
)
switch mtProfile {
@@ -356,16 +361,8 @@ func (o *Dispatcher) createForwardMessage(msg []byte, des *service.Destination)
transport.MediaTypeAIP2RFC0587Profile, transport.MediaTypeV2PlaintextPayload, transport.MediaTypeDIDCommV2Profile:
// for DIDComm V2, do not set senderKey to force Anoncrypt packing. Only set the V2 forwardMsgType.
forwardMsgType = service.ForwardMsgTypeV2
- default: // default is DIDComm V1, create a dummy key as senderKey
- // create key set
- _, senderKey, err = o.kms.CreateAndExportPubKeyBytes(kms.ED25519Type)
- if err != nil {
- return nil, fmt.Errorf("failed Create and export Encryption Key: %w", err)
- }
-
- senderDIDKey, _ := fingerprint.CreateDIDKey(senderKey)
-
- senderKey = []byte(senderDIDKey)
+ default: // default is DIDComm V1
+ forwardMsgType = service.ForwardMsgType
}
routingKeys, err := des.ServiceEndpoint.RoutingKeys()
@@ -382,26 +379,74 @@ func (o *Dispatcher) createForwardMessage(msg []byte, des *service.Destination)
routingKeys = des.RoutingKeys
}
- // create forward message
- forward := &model.Forward{
- Type: forwardMsgType,
- ID: uuid.New().String(),
- To: des.RecipientKeys[0],
- Msg: msg,
+ fwdKeys := append([]string{des.RecipientKeys[0]}, routingKeys...)
+
+ packedMsg, err := o.createPackedNestedForwards(msg, fwdKeys, forwardMsgType, mtProfile)
+ if err != nil {
+ return nil, fmt.Errorf("failed to create packed nested forwards: %w", err)
+ }
+
+ return packedMsg, nil
+}
+
+func (o *Dispatcher) createPackedNestedForwards(msg []byte, routingKeys []string, fwdMsgType, mtProfile string) ([]byte, error) { //nolint: lll
+ for i, key := range routingKeys {
+ if i+1 >= len(routingKeys) {
+ break
+ }
+ // create forward message
+ forward := model.Forward{
+ Type: fwdMsgType,
+ ID: uuid.New().String(),
+ To: key,
+ Msg: msg,
+ }
+
+ var err error
+
+ msg, err = o.packForward(forward, []string{routingKeys[i+1]}, mtProfile)
+ if err != nil {
+ return nil, fmt.Errorf("failed to pack forward msg: %w", err)
+ }
}
+ return msg, nil
+}
+
+func (o *Dispatcher) packForward(fwd model.Forward, toKeys []string, mtProfile string) ([]byte, error) {
+ env := &model.Envelope{}
+
+ var (
+ forward interface{}
+ err error
+ req []byte
+ )
+ // try to convert msg to Envelope
+ err = json.Unmarshal(fwd.Msg, env)
+ if err == nil {
+ forward = legacyForward{
+ Type: fwd.Type,
+ ID: fwd.ID,
+ To: fwd.To,
+ Msg: env,
+ }
+ } else {
+ forward = fwd
+ }
// convert forward message to bytes
- req, err := json.Marshal(forward)
+ req, err = json.Marshal(forward)
if err != nil {
return nil, fmt.Errorf("failed marshal to bytes: %w", err)
}
- packedMsg, err := o.packager.PackMessage(&transport.Envelope{
+ var packedMsg []byte
+ packedMsg, err = o.packager.PackMessage(&transport.Envelope{
MediaTypeProfile: mtProfile,
Message: req,
- FromKey: senderKey,
- ToKeys: routingKeys,
+ FromKey: []byte{},
+ ToKeys: toKeys,
})
+
if err != nil {
return nil, fmt.Errorf("failed to pack forward msg: %w", err)
}
diff --git a/pkg/didcomm/dispatcher/outbound/outbound_test.go b/pkg/didcomm/dispatcher/outbound/outbound_test.go
index 545da6d96..2298fafa6 100644
--- a/pkg/didcomm/dispatcher/outbound/outbound_test.go
+++ b/pkg/didcomm/dispatcher/outbound/outbound_test.go
@@ -13,6 +13,7 @@ import (
"testing"
"github.com/google/uuid"
+ "github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
"github.com/hyperledger/aries-framework-go/pkg/common/model"
@@ -47,6 +48,38 @@ func TestNewOutbound(t *testing.T) {
})
}
+func TestOutBoundDispatcher_createPackedNestedForwards(t *testing.T) {
+ t.Run("test send with nested forward message - success", func(t *testing.T) {
+ data := "data"
+ recKey1 := "recKey1"
+ rtKey1 := "rtKey1"
+ rtKey2 := "rtKey2"
+ packager := &mockPackager{}
+ expectedRequest := `{"protected":"","iv":"","ciphertext":"","tag":""}`
+
+ o, err := NewOutbound(&mockProvider{
+ packagerValue: packager,
+ outboundTransportsValue: []transport.OutboundTransport{&mockOutboundTransport{expectedRequest: expectedRequest}},
+ storageProvider: mockstore.NewMockStoreProvider(),
+ protoStorageProvider: mockstore.NewMockStoreProvider(),
+ mediaTypeProfiles: []string{transport.MediaTypeDIDCommV2Profile},
+ })
+ require.NoError(t, err)
+
+ packager.On("PackMessage", []string{recKey1}).Return([]byte(expectedRequest))
+ packager.On("PackMessage", []string{rtKey1}).Return([]byte(expectedRequest))
+ packager.On("PackMessage", []string{rtKey2}).Return([]byte(expectedRequest))
+
+ require.NoError(t, o.Send(data, "", &service.Destination{
+ ServiceEndpoint: model.NewDIDCommV2Endpoint([]model.DIDCommV2Endpoint{
+ {URI: "url", RoutingKeys: []string{rtKey1, rtKey2}},
+ }),
+ RecipientKeys: []string{recKey1},
+ }))
+ packager.AssertExpectations(t)
+ })
+}
+
func TestOutboundDispatcher_Send(t *testing.T) {
t.Run("test success", func(t *testing.T) {
o, err := NewOutbound(&mockProvider{
@@ -173,29 +206,6 @@ func TestOutboundDispatcher_Send(t *testing.T) {
}))
})
- t.Run("test send with forward message - create key failure", func(t *testing.T) {
- o, err := NewOutbound(&mockProvider{
- packagerValue: &mockpackager.Packager{PackValue: createPackedMsgForForward(t)},
- outboundTransportsValue: []transport.OutboundTransport{&mockdidcomm.MockOutboundTransport{AcceptValue: true}},
- kms: &mockkms.KeyManager{
- CrAndExportPubKeyErr: errors.New("create and export key error"),
- },
- storageProvider: mockstore.NewMockStoreProvider(),
- protoStorageProvider: mockstore.NewMockStoreProvider(),
- mediaTypeProfiles: []string{transport.MediaTypeAIP2RFC0019Profile},
- })
- require.NoError(t, err)
-
- err = o.Send("data", mockdiddoc.MockDIDKey(t), &service.Destination{
- ServiceEndpoint: model.NewDIDCommV2Endpoint([]model.DIDCommV2Endpoint{
- {URI: "url", RoutingKeys: []string{"xyz"}},
- }),
- RecipientKeys: []string{"abc"},
- })
- require.EqualError(t, err, "outboundDispatcher.Send: failed to create forward msg: failed Create "+
- "and export Encryption Key: create and export key error")
- })
-
t.Run("test send with forward message - packer error", func(t *testing.T) {
o, err := NewOutbound(&mockProvider{
packagerValue: &mockpackager.Packager{PackErr: errors.New("pack error")},
@@ -778,9 +788,21 @@ func (o *mockOutboundTransport) Accept(url string) bool {
}
// mockPackager mock packager.
-type mockPackager struct{}
+type mockPackager struct {
+ mock.Mock
+}
func (m *mockPackager) PackMessage(e *transport.Envelope) ([]byte, error) {
+ if len(m.ExpectedCalls) > 0 {
+ args := m.Called(e.ToKeys)
+ switch v := args.Get(0).(type) {
+ case []byte:
+ return v, nil
+ default:
+ return e.Message, nil
+ }
+ }
+
return e.Message, nil
}
diff --git a/pkg/didcomm/packager/packager.go b/pkg/didcomm/packager/packager.go
index 89cef7167..0aa758a50 100644
--- a/pkg/didcomm/packager/packager.go
+++ b/pkg/didcomm/packager/packager.go
@@ -18,6 +18,7 @@ import (
"github.com/hyperledger/aries-framework-go/pkg/crypto"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/packer"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/packer/authcrypt"
+ legacyAuthCrypt "github.com/hyperledger/aries-framework-go/pkg/didcomm/packer/legacy/authcrypt"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/transport"
"github.com/hyperledger/aries-framework-go/pkg/doc/did"
"github.com/hyperledger/aries-framework-go/pkg/doc/jose/jwk/jwksupport"
@@ -83,8 +84,10 @@ func New(ctx Provider) (*Packager, error) {
func (bp *Packager) addPacker(pack packer.Packer) {
packerID := pack.EncodingType()
- _, ok := pack.(*authcrypt.Packer)
- if ok {
+ _, isAuthCrypt := pack.(*authcrypt.Packer)
+ _, isLegacyAuthCrypt := pack.(*legacyAuthCrypt.Packer)
+
+ if isAuthCrypt || isLegacyAuthCrypt {
// anoncrypt and authcrypt have the same encoding type
// so authcrypt will have an appended suffix
packerID += authSuffix
@@ -276,6 +279,7 @@ type envelopeStub struct {
type headerStub struct {
Type string `json:"typ,omitempty"`
SKID string `json:"skid,omitempty"`
+ Alg string `json:"alg,omitempty"`
}
//nolint:funlen, gocyclo
@@ -349,7 +353,7 @@ func getEncodingType(encMessage []byte) (string, []byte, error) {
packerID := prot.Type
- if prot.SKID != "" {
+ if prot.SKID != "" || prot.Alg == "Authcrypt" {
// since Type protected header is the same for authcrypt and anoncrypt, the differentiating factor is SKID.
// If it is present, then it's authcrypt.
packerID += authSuffix
@@ -385,22 +389,20 @@ func (bp *Packager) UnpackMessage(encMessage []byte) (*transport.Envelope, error
func (bp *Packager) getCTYAndPacker(envelope *transport.Envelope) (string, packer.Packer, error) {
switch envelope.MediaTypeProfile {
case transport.MediaTypeAIP2RFC0019Profile, transport.MediaTypeProfileDIDCommAIP1:
- return transport.MediaTypeRFC0019EncryptedEnvelope, bp.packers[transport.MediaTypeRFC0019EncryptedEnvelope], nil
+ packerName := addAuthcryptSuffix(envelope.FromKey, transport.MediaTypeRFC0019EncryptedEnvelope)
+
+ return transport.MediaTypeRFC0019EncryptedEnvelope, bp.packers[packerName], nil
case transport.MediaTypeRFC0019EncryptedEnvelope:
- return envelope.MediaTypeProfile, bp.packers[transport.MediaTypeRFC0019EncryptedEnvelope], nil
+ packerName := addAuthcryptSuffix(envelope.FromKey, transport.MediaTypeRFC0019EncryptedEnvelope)
+
+ return envelope.MediaTypeProfile, bp.packers[packerName], nil
case transport.MediaTypeV2EncryptedEnvelope, transport.MediaTypeV2PlaintextPayload,
transport.MediaTypeAIP2RFC0587Profile, transport.MediaTypeDIDCommV2Profile:
- packerName := transport.MediaTypeV2EncryptedEnvelope
- if len(envelope.FromKey) > 0 {
- packerName += authSuffix
- }
+ packerName := addAuthcryptSuffix(envelope.FromKey, transport.MediaTypeV2EncryptedEnvelope)
return transport.MediaTypeV2PlaintextPayload, bp.packers[packerName], nil
case transport.MediaTypeV2EncryptedEnvelopeV1PlaintextPayload, transport.MediaTypeV1PlaintextPayload:
- packerName := transport.MediaTypeV2EncryptedEnvelope
- if len(envelope.FromKey) > 0 {
- packerName += authSuffix
- }
+ packerName := addAuthcryptSuffix(envelope.FromKey, transport.MediaTypeV2EncryptedEnvelope)
return transport.MediaTypeV1PlaintextPayload, bp.packers[packerName], nil
default:
@@ -415,6 +417,14 @@ func (bp *Packager) getCTYAndPacker(envelope *transport.Envelope) (string, packe
return "", nil, fmt.Errorf("no packer found for mediatype profile: '%v'", envelope.MediaTypeProfile)
}
+func addAuthcryptSuffix(fromKey []byte, packerName string) string {
+ if len(fromKey) > 0 {
+ packerName += authSuffix
+ }
+
+ return packerName
+}
+
func (bp *Packager) resolveKeyAgreementFromDIDDoc(keyAgrID string) (*crypto.PublicKey, error) {
i := strings.Index(keyAgrID, "#")
diff --git a/pkg/didcomm/protocol/mediator/service.go b/pkg/didcomm/protocol/mediator/service.go
index e1a29689e..3c0c965e9 100644
--- a/pkg/didcomm/protocol/mediator/service.go
+++ b/pkg/didcomm/protocol/mediator/service.go
@@ -22,6 +22,7 @@ import (
"github.com/hyperledger/aries-framework-go/pkg/didcomm/dispatcher"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/decorator"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/messagepickup"
+ "github.com/hyperledger/aries-framework-go/pkg/didcomm/transport"
"github.com/hyperledger/aries-framework-go/pkg/doc/util/kmsdidkey"
"github.com/hyperledger/aries-framework-go/pkg/framework/aries/api/vdr"
"github.com/hyperledger/aries-framework-go/pkg/internal/logutil"
@@ -391,31 +392,29 @@ func (s *Service) handleInboundRequest(c *callback) error {
c.msg.ID(),
c.options,
s.endpoint,
- func() ([]string, error) {
- if len(s.mediaTypeProfiles) > 0 {
- _, pubKeyBytes, e := s.kms.CreateAndExportPubKeyBytes(s.keyAgreementType)
- if e != nil {
- return nil, fmt.Errorf("outboundGrant from handleInboundRequest: kms failed to create "+
- "and export %v key: %w", s.keyAgreementType, e)
+ func() (string, error) {
+ for _, mtp := range s.mediaTypeProfiles {
+ switch mtp {
+ case transport.MediaTypeDIDCommV2Profile, transport.MediaTypeAIP2RFC0587Profile:
+ _, pubKeyBytes, e := s.kms.CreateAndExportPubKeyBytes(s.keyAgreementType)
+ if e != nil {
+ return "", fmt.Errorf("outboundGrant from handleInboundRequest: kms failed to create "+
+ "and export %v key: %w", s.keyAgreementType, e)
+ }
+
+ return kmsdidkey.BuildDIDKeyByKeyType(pubKeyBytes, s.keyAgreementType)
}
+ }
- didCommV2Key, errBuild := kmsdidkey.BuildDIDKeyByKeyType(pubKeyBytes, s.keyAgreementType)
- if errBuild != nil {
- return nil, errBuild
- }
-
- _, pubKeyBytes, er := s.kms.CreateAndExportPubKeyBytes(kms.ED25519Type)
- if er != nil {
- return nil, fmt.Errorf("outboundGrant from handleInboundRequest: kms failed to create and "+
- "export ED25519 key: %w", er)
- }
-
- didKey, _ := fingerprint.CreateDIDKey(pubKeyBytes)
-
- return []string{didKey, didCommV2Key}, nil
+ _, pubKeyBytes, er := s.kms.CreateAndExportPubKeyBytes(kms.ED25519Type)
+ if er != nil {
+ return "", fmt.Errorf("outboundGrant from handleInboundRequest: kms failed to create and "+
+ "export ED25519 key: %w", er)
}
- return nil, nil
+ didKey, _ := fingerprint.CreateDIDKey(pubKeyBytes)
+
+ return didKey, er
},
)
if err != nil {
@@ -427,7 +426,7 @@ func (s *Service) handleInboundRequest(c *callback) error {
func outboundGrant(
msgID string, opts *Options,
- defaultEndpoint string, defaultKey func() ([]string, error)) (*Grant, error) {
+ defaultEndpoint string, defaultKey func() (string, error)) (*Grant, error) {
grant := &Grant{
ID: msgID,
Type: GrantMsgType,
@@ -445,7 +444,7 @@ func outboundGrant(
return nil, fmt.Errorf("outboundGrant: failed to create keys : %w", err)
}
- grant.RoutingKeys = keys
+ grant.RoutingKeys = []string{keys}
}
logger.Debugf("outbound grant: %+v", grant)
diff --git a/pkg/framework/aries/default.go b/pkg/framework/aries/default.go
index 101a0afa1..f02b1dd49 100644
--- a/pkg/framework/aries/default.go
+++ b/pkg/framework/aries/default.go
@@ -16,7 +16,8 @@ import (
"github.com/hyperledger/aries-framework-go/pkg/didcomm/packer"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/packer/anoncrypt"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/packer/authcrypt"
- legacy "github.com/hyperledger/aries-framework-go/pkg/didcomm/packer/legacy/authcrypt"
+ legacyAnonCrypt "github.com/hyperledger/aries-framework-go/pkg/didcomm/packer/legacy/anoncrypt"
+ legacyAuthCrypt "github.com/hyperledger/aries-framework-go/pkg/didcomm/packer/legacy/authcrypt"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/didexchange"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/introduce"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/issuecredential"
@@ -244,13 +245,17 @@ func setAdditionalDefaultOpts(frameworkOpts *Aries) error {
if frameworkOpts.packerCreator == nil {
frameworkOpts.packerCreator = func(provider packer.Provider) (packer.Packer, error) {
- return legacy.New(provider), nil
+ return legacyAuthCrypt.New(provider), nil
}
frameworkOpts.packerCreators = []packer.Creator{
func(provider packer.Provider) (packer.Packer, error) {
- return legacy.New(provider), nil
+ return legacyAuthCrypt.New(provider), nil
},
+ func(provider packer.Provider) (packer.Packer, error) {
+ return legacyAnonCrypt.New(provider), nil
+ },
+
func(provider packer.Provider) (packer.Packer, error) {
return authcrypt.New(provider, jose.A256CBCHS512)
},
diff --git a/test/bdd/go.mod b/test/bdd/go.mod
index 2e0cf9388..a4e6c8447 100644
--- a/test/bdd/go.mod
+++ b/test/bdd/go.mod
@@ -74,6 +74,7 @@ require (
github.com/sirupsen/logrus v1.7.0 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/square/go-jose/v3 v3.0.0-20200630053402-0a67ce9b0693 // indirect
+ github.com/stretchr/objx v0.4.0 // indirect
github.com/stretchr/testify v1.7.2 // indirect
github.com/syndtr/goleveldb v1.0.0 // indirect
github.com/tidwall/gjson v1.6.7 // indirect
diff --git a/test/bdd/go.sum b/test/bdd/go.sum
index a8b63d9d4..9269ff6ef 100644
--- a/test/bdd/go.sum
+++ b/test/bdd/go.sum
@@ -447,11 +447,14 @@ github.com/square/go-jose/v3 v3.0.0-20200630053402-0a67ce9b0693 h1:wD1IWQwAhdWcl
github.com/square/go-jose/v3 v3.0.0-20200630053402-0a67ce9b0693/go.mod h1:6hSY48PjDm4UObWmGLyJE9DxYVKTgR9kbCspXXJEhcU=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s=
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=