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

Commit

Permalink
refactor: Enable usage of legacy Anoncrypt packer. Make nested forwar…
Browse files Browse the repository at this point in the history
…ds 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 04bfea8 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 <abdulbois.tursunov@avast.com>
  • Loading branch information
Abdulbois committed Jul 16, 2022
1 parent 891248e commit df4a167
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 69 deletions.
70 changes: 40 additions & 30 deletions pkg/didcomm/dispatcher/outbound/outbound.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)

Expand Down Expand Up @@ -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#corerouting10forward
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.
Expand Down Expand Up @@ -341,30 +349,20 @@ func (o *Dispatcher) Forward(msg interface{}, des *service.Destination) error {
}

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 {
case transport.MediaTypeV2EncryptedEnvelopeV1PlaintextPayload, transport.MediaTypeV2EncryptedEnvelope,
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()
Expand All @@ -383,36 +381,29 @@ func (o *Dispatcher) createForwardMessage(msg []byte, des *service.Destination)

fwdKeys := append([]string{des.RecipientKeys[0]}, routingKeys...)

packedMsg, err := o.createPackedNestedForwards(msg, senderKey, fwdKeys, forwardMsgType, mtProfile)
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, senderKey []byte, routingKeys []string, fwdMsgType, mtProfile string) ([]byte, error) { //nolint: lll
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
}

msgEnv := &model.Envelope{}

err := json.Unmarshal(msg, msgEnv)
if err != nil {
return nil, fmt.Errorf("failed unmarshal to Envelope: %w", err)
}

// create forward message
forward := model.Forward{
Type: fwdMsgType,
ID: uuid.New().String(),
To: key,
Msg: msgEnv,
Msg: msg,
}
var err error

msg, err = o.packForward(forward, []string{routingKeys[i+1]}, senderKey, mtProfile)
msg, err = o.packForward(forward, []string{routingKeys[i+1]}, mtProfile)
if err != nil {
return nil, fmt.Errorf("failed to pack forward msg: %w", err)
}
Expand All @@ -421,9 +412,28 @@ func (o *Dispatcher) createPackedNestedForwards(msg, senderKey []byte, routingKe
return msg, nil
}

func (o *Dispatcher) packForward(fwd model.Forward, toKeys []string, senderKey []byte, mtProfile string) ([]byte, error) { //nolint: lll
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(fwd)
req, err = json.Marshal(forward)
if err != nil {
return nil, fmt.Errorf("failed marshal to bytes: %w", err)
}
Expand All @@ -432,7 +442,7 @@ func (o *Dispatcher) packForward(fwd model.Forward, toKeys []string, senderKey [
packedMsg, err = o.packager.PackMessage(&transport.Envelope{
MediaTypeProfile: mtProfile,
Message: req,
FromKey: senderKey,
FromKey: []byte{},
ToKeys: toKeys,
})

Expand Down
34 changes: 21 additions & 13 deletions pkg/didcomm/packager/packager.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"encoding/json"
"errors"
"fmt"
legacyAuthCrypt "github.com/hyperledger/aries-framework-go/pkg/didcomm/packer/legacy/authcrypt"
"strings"

"github.com/hyperledger/aries-framework-go/pkg/common/log"
Expand Down Expand Up @@ -83,8 +84,9 @@ 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
Expand Down Expand Up @@ -276,6 +278,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
Expand Down Expand Up @@ -349,7 +352,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
Expand Down Expand Up @@ -385,22 +388,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:
Expand All @@ -415,6 +416,13 @@ 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, "#")

Expand Down
45 changes: 22 additions & 23 deletions pkg/didcomm/protocol/mediator/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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 {
Expand All @@ -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,
Expand All @@ -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)
Expand Down
11 changes: 8 additions & 3 deletions pkg/framework/aries/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
},
Expand Down

0 comments on commit df4a167

Please sign in to comment.