This repository has been archived by the owner on Mar 27, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 158
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Connection protocol (RFC-0160) DIDCommV1 implementation (partia…
…lly) - Add implementation only for protocol's package - Enable to handle "did:key" keys while creating legacy forwards. - Add legacy profile types and use them while checking transport types. Signed-off-by: Abdulbois <abdulbois.tursunov@avast.com>
- Loading branch information
Showing
14 changed files
with
5,871 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
/* | ||
Copyright Avast Software. All Rights Reserved. | ||
SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package legacyconnection | ||
|
||
// connectionEvent implements connection.Event interface. | ||
type connectionEvent struct { | ||
connectionID string | ||
invitationID string | ||
} | ||
|
||
// ConnectionID returns Connection connectionID. | ||
func (ex *connectionEvent) ConnectionID() string { | ||
return ex.connectionID | ||
} | ||
|
||
// InvitationID returns Connection invitationID. | ||
func (ex *connectionEvent) InvitationID() string { | ||
return ex.invitationID | ||
} | ||
|
||
// connectionEventError for sending events with processing error. | ||
type connectionEventError struct { | ||
connectionEvent | ||
err error | ||
} | ||
|
||
// Error implements error interface. | ||
func (ex *connectionEventError) Error() string { | ||
if ex.err != nil { | ||
return ex.err.Error() | ||
} | ||
|
||
return "" | ||
} | ||
|
||
// All implements EventProperties interface. | ||
func (ex *connectionEvent) All() map[string]interface{} { | ||
return map[string]interface{}{ | ||
"connectionID": ex.ConnectionID(), | ||
"invitationID": ex.InvitationID(), | ||
} | ||
} | ||
|
||
// All implements EventProperties interface. | ||
func (ex *connectionEventError) All() map[string]interface{} { | ||
return map[string]interface{}{ | ||
"connectionID": ex.ConnectionID(), | ||
"invitationID": ex.InvitationID(), | ||
"error": ex.Error(), | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/* | ||
Copyright Avast Software. All Rights Reserved. | ||
SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package legacyconnection | ||
|
||
import ( | ||
"errors" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestConnectionEvent(t *testing.T) { | ||
ev := connectionEvent{connectionID: "abc", invitationID: "xyz"} | ||
require.Equal(t, ev.ConnectionID(), "abc") | ||
require.Equal(t, ev.InvitationID(), "xyz") | ||
require.Equal(t, ev.All()["connectionID"], ev.ConnectionID()) | ||
require.Equal(t, ev.All()["invitationID"], ev.InvitationID()) | ||
|
||
err := errors.New("processing error") | ||
evErr := connectionEventError{err: err} | ||
require.Equal(t, err.Error(), evErr.Error()) | ||
require.Equal(t, evErr.All()["error"], evErr.Error()) | ||
|
||
evErr = connectionEventError{} | ||
require.Equal(t, "", evErr.Error()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
/* | ||
Copyright Avast Software. All Rights Reserved. | ||
SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package legacyconnection | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
|
||
"github.com/hyperledger/aries-framework-go/pkg/crypto" | ||
"github.com/hyperledger/aries-framework-go/pkg/doc/did" | ||
"github.com/hyperledger/aries-framework-go/pkg/kms" | ||
) | ||
|
||
func (ctx *context) createNewKeyAndVM(didDoc *did.Doc) error { | ||
vm, err := ctx.createSigningVM() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
kaVM, err := ctx.createEncryptionVM() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
didDoc.VerificationMethod = append(didDoc.VerificationMethod, *vm) | ||
didDoc.Authentication = append(didDoc.Authentication, *did.NewEmbeddedVerification(vm, did.Authentication)) | ||
// FIXME is KeyAgreement needed? | ||
didDoc.KeyAgreement = append(didDoc.KeyAgreement, *did.NewEmbeddedVerification(kaVM, did.KeyAgreement)) | ||
|
||
return nil | ||
} | ||
|
||
func (ctx *context) createSigningVM() (*did.VerificationMethod, error) { | ||
vmType := getVerMethodType(ctx.keyType) | ||
|
||
_, pubKeyBytes, err := ctx.kms.CreateAndExportPubKeyBytes(ctx.keyType) | ||
if err != nil { | ||
return nil, fmt.Errorf("createSigningVM: %w", err) | ||
} | ||
|
||
vmID := "#key-1" | ||
|
||
switch vmType { | ||
case ed25519VerificationKey2018: | ||
return did.NewVerificationMethodFromBytes(vmID, vmType, "", pubKeyBytes), nil | ||
default: | ||
return nil, fmt.Errorf("createSigningVM: unsupported verification method: '%s'", vmType) | ||
} | ||
} | ||
|
||
func (ctx *context) createEncryptionVM() (*did.VerificationMethod, error) { | ||
encKeyType := ctx.keyAgreementType | ||
|
||
vmType := getVerMethodType(encKeyType) | ||
|
||
_, kaPubKeyBytes, err := ctx.kms.CreateAndExportPubKeyBytes(encKeyType) | ||
if err != nil { | ||
return nil, fmt.Errorf("createEncryptionVM: %w", err) | ||
} | ||
|
||
vmID := "#key-2" | ||
|
||
switch vmType { | ||
case x25519KeyAgreementKey2019: | ||
key := &crypto.PublicKey{} | ||
|
||
err = json.Unmarshal(kaPubKeyBytes, key) | ||
if err != nil { | ||
return nil, fmt.Errorf("createEncryptionVM: unable to unmarshal X25519 key: %w", err) | ||
} | ||
|
||
return did.NewVerificationMethodFromBytes(vmID, vmType, "", key.X), nil | ||
default: | ||
return nil, fmt.Errorf("unsupported verification method for KeyAgreement: '%s'", vmType) | ||
} | ||
} | ||
|
||
// nolint:gochecknoglobals | ||
var vmType = map[kms.KeyType]string{ | ||
kms.ED25519Type: ed25519VerificationKey2018, | ||
kms.X25519ECDHKWType: x25519KeyAgreementKey2019, | ||
} | ||
|
||
func getVerMethodType(kt kms.KeyType) string { | ||
return vmType[kt] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
/* | ||
Copyright Avast Software. All Rights Reserved. | ||
SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package legacyconnection | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
|
||
"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/mediator" | ||
"github.com/hyperledger/aries-framework-go/pkg/doc/did" | ||
"github.com/hyperledger/aries-framework-go/pkg/kms" | ||
"github.com/hyperledger/aries-framework-go/pkg/mock/didcomm/protocol" | ||
mockroute "github.com/hyperledger/aries-framework-go/pkg/mock/didcomm/protocol/mediator" | ||
mockstorage "github.com/hyperledger/aries-framework-go/pkg/mock/storage" | ||
) | ||
|
||
func TestCreateNewKeyAndVM(t *testing.T) { | ||
k := newKMS(t, mockstorage.NewMockStoreProvider()) | ||
|
||
p, err := New(&protocol.MockProvider{ | ||
ServiceMap: map[string]interface{}{ | ||
mediator.Coordination: &mockroute.MockMediatorSvc{}, | ||
}, | ||
CustomKMS: k, | ||
}) | ||
require.NoError(t, err) | ||
|
||
t.Run("createNewKeyAndVM success", func(t *testing.T) { | ||
didDoc := &did.Doc{} | ||
|
||
p.ctx.keyType = kms.ED25519 | ||
p.ctx.keyAgreementType = kms.X25519ECDHKWType | ||
|
||
err = p.ctx.createNewKeyAndVM(didDoc) | ||
require.NoError(t, err) | ||
require.Equal(t, ed25519VerificationKey2018, didDoc.VerificationMethod[0].Type) | ||
require.Equal(t, x25519KeyAgreementKey2019, didDoc.KeyAgreement[0].VerificationMethod.Type) | ||
}) | ||
|
||
t.Run("createNewKeyAndVM invalid keyType export signing key", func(t *testing.T) { | ||
didDoc := &did.Doc{} | ||
|
||
p.ctx.keyType = kms.HMACSHA256Tag256Type // invalid signing key | ||
p.ctx.keyAgreementType = kms.X25519ECDHKWType | ||
|
||
err = p.ctx.createNewKeyAndVM(didDoc) | ||
require.EqualError(t, err, "createSigningVM: createAndExportPubKeyBytes: failed to export new public key bytes: "+ | ||
"exportPubKeyBytes: failed to export marshalled key: exportPubKeyBytes: failed to get public keyset "+ | ||
"handle: keyset.Handle: keyset.Handle: keyset contains a non-private key") | ||
require.Empty(t, didDoc.VerificationMethod) | ||
require.Empty(t, didDoc.KeyAgreement) | ||
}) | ||
} | ||
|
||
func TestCreateSigningVM(t *testing.T) { | ||
k := newKMS(t, mockstorage.NewMockStoreProvider()) | ||
|
||
p, err := New(&protocol.MockProvider{ | ||
ServiceMap: map[string]interface{}{ | ||
mediator.Coordination: &mockroute.MockMediatorSvc{}, | ||
}, | ||
CustomKMS: k, | ||
}) | ||
require.NoError(t, err) | ||
|
||
t.Run("createSigningVM success", func(t *testing.T) { | ||
p.ctx.keyType = kms.ED25519 | ||
|
||
svm, err := p.ctx.createSigningVM() | ||
require.NoError(t, err) | ||
require.NotEmpty(t, svm) | ||
}) | ||
|
||
t.Run("createSigningVM with empty vmType", func(t *testing.T) { | ||
p.ctx.keyType = "" | ||
|
||
svm, err := p.ctx.createSigningVM() | ||
require.EqualError(t, err, "createSigningVM: createAndExportPubKeyBytes: failed to create new key: "+ | ||
"failed to create new key, missing key type") | ||
require.Empty(t, svm) | ||
}) | ||
|
||
t.Run("createSigningVM with unsupported keyType", func(t *testing.T) { | ||
p.ctx.keyType = kms.X25519ECDHKW | ||
|
||
svm, err := p.ctx.createSigningVM() | ||
require.EqualError(t, err, "createSigningVM: unsupported verification method: 'X25519KeyAgreementKey2019'") | ||
require.Empty(t, svm) | ||
}) | ||
} | ||
|
||
func TestCreateEncryptionVM(t *testing.T) { | ||
k := newKMS(t, mockstorage.NewMockStoreProvider()) | ||
|
||
p, err := New(&protocol.MockProvider{ | ||
ServiceMap: map[string]interface{}{ | ||
mediator.Coordination: &mockroute.MockMediatorSvc{}, | ||
}, | ||
CustomKMS: k, | ||
}) | ||
require.NoError(t, err) | ||
|
||
t.Run("createEncryptionVM success", func(t *testing.T) { | ||
p.ctx.keyAgreementType = kms.X25519ECDHKW | ||
|
||
evm, err := p.ctx.createEncryptionVM() | ||
require.NoError(t, err) | ||
require.NotEmpty(t, evm) | ||
}) | ||
|
||
t.Run("createEncryptionVM with empty keyAgreementType", func(t *testing.T) { | ||
p.ctx.keyAgreementType = "" | ||
|
||
evm, err := p.ctx.createEncryptionVM() | ||
require.EqualError(t, err, "createEncryptionVM: createAndExportPubKeyBytes: failed to create new key: "+ | ||
"failed to create new key, missing key type") | ||
require.Empty(t, evm) | ||
}) | ||
|
||
t.Run("createEncryptionVM with unsupported keyType", func(t *testing.T) { | ||
p.ctx.keyAgreementType = kms.ED25519Type | ||
|
||
evm, err := p.ctx.createEncryptionVM() | ||
require.EqualError(t, err, "unsupported verification method for KeyAgreement: 'Ed25519VerificationKey2018'") | ||
require.Empty(t, evm) | ||
}) | ||
} |
Oops, something went wrong.