Skip to content
This repository has been archived by the owner on Apr 5, 2023. It is now read-only.

Commit

Permalink
fix: authorization cred DID docs support didcomm/aip2;env=rfc587
Browse files Browse the repository at this point in the history
Signed-off-by: Filip Burlacu <filip.burlacu@securekey.com>
  • Loading branch information
Filip Burlacu committed Feb 28, 2022
1 parent c43795d commit 71cc3fd
Show file tree
Hide file tree
Showing 6 changed files with 386 additions and 17 deletions.
2 changes: 2 additions & 0 deletions pkg/restapi/issuer/operation/operations.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,8 @@ func New(config *Config) (*Operation, error) { // nolint:funlen,gocyclo,cyclop
ConnectionLookup: connectionLookup,
MediatorSvc: mediatorSvc,
KeyManager: config.AriesCtx.KMS(),
KeyType: config.AriesCtx.KeyType(),
KeyAgrType: config.AriesCtx.KeyAgreementType(),
})
if err != nil {
return nil, fmt.Errorf("create message service : %w", err)
Expand Down
3 changes: 3 additions & 0 deletions pkg/restapi/issuer/operation/support_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
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/verifiable"
"github.com/hyperledger/aries-framework-go/pkg/kms"
mockcrypto "github.com/hyperledger/aries-framework-go/pkg/mock/crypto"
mocksvc "github.com/hyperledger/aries-framework-go/pkg/mock/didcomm/protocol/didexchange"
mockroute "github.com/hyperledger/aries-framework-go/pkg/mock/didcomm/protocol/mediator"
Expand Down Expand Up @@ -79,6 +80,8 @@ func getAriesCtx(t *testing.T) aries.CtxProvider {
CreateValue: mockdiddoc.GetMockDIDDoc("did:example:def567"),
ResolveValue: mockdiddoc.GetMockDIDDoc("did:example:def567"),
},
KeyTypeValue: kms.ED25519Type,
KeyAgreementTypeValue: kms.ED25519Type,
},
}
}
Expand Down
2 changes: 2 additions & 0 deletions pkg/restapi/rp/operation/operations.go
Original file line number Diff line number Diff line change
Expand Up @@ -1858,6 +1858,8 @@ func createRouteSvc(config *Config, connectionLookup connectionRecorder) (routeS
ConnectionLookup: connectionLookup,
MediatorSvc: mediatorSvc,
KeyManager: config.AriesContextProvider.KMS(),
KeyType: config.AriesContextProvider.KeyType(),
KeyAgrType: config.AriesContextProvider.KeyAgreementType(),
})
if err != nil {
return nil, fmt.Errorf("create service : %w", err)
Expand Down
105 changes: 88 additions & 17 deletions pkg/route/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,26 @@ SPDX-License-Identifier: Apache-2.0
package route

import (
"encoding/json"
"errors"
"fmt"
"strings"

"github.com/google/uuid"
"github.com/hyperledger/aries-framework-go/pkg/client/didexchange"
ariescrypto "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/messaging/msghandler"
mediatorsvc "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/doc/util/jwkkid"
"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/vdr/peer"
"github.com/hyperledger/aries-framework-go/spi/storage"
"github.com/trustbloc/edge-core/pkg/log"

"github.com/trustbloc/edge-adapter/pkg/aries/message"
"github.com/trustbloc/edge-adapter/pkg/crypto"
)

// Msg svc constants.
Expand All @@ -36,8 +39,9 @@ const (
)

const (
txnStoreName = "msgsvc_txn"
didCommServiceType = "did-communication"
txnStoreName = "msgsvc_txn"
didCommServiceType = "did-communication"
didCommV2ServiceType = "DIDCommMessaging"
)

var logger = log.New("edge-adapter/msgsvc")
Expand Down Expand Up @@ -69,6 +73,8 @@ type Config struct {
ConnectionLookup connectionRecorder
MediatorSvc mediatorsvc.ProtocolService
KeyManager kms.KeyManager
KeyType kms.KeyType
KeyAgrType kms.KeyType
}

// Service svc.
Expand All @@ -82,6 +88,8 @@ type Service struct {
connectionLookup connectionRecorder
mediatorSvc mediatorsvc.ProtocolService
keyManager kms.KeyManager
keyType kms.KeyType
keyAgrType kms.KeyType
}

// New returns a new Service.
Expand All @@ -102,6 +110,8 @@ func New(config *Config) (*Service, error) {
// TODO https://github.com/trustbloc/edge-adapter/issues/361 use function from client
mediatorSvc: config.MediatorSvc,
keyManager: config.KeyManager,
keyType: config.KeyType,
keyAgrType: config.KeyAgrType,
}

msgCh := make(chan message.Msg, 1)
Expand All @@ -122,11 +132,18 @@ func New(config *Config) (*Service, error) {
// GetDIDDoc returns the did doc with router endpoint/keys if its registered, else returns the doc
// with default endpoint.
func (o *Service) GetDIDDoc(connID string, requiresBlindedRoute bool) (*did.Doc, error) { //nolint:gocyclo,funlen,cyclop
verMethod, err := o.newVerificationMethod()
verMethod, err := o.newVerificationMethod(kms.ED25519Type)
if err != nil {
return nil, fmt.Errorf("failed to create new verification method: %w", err)
}

kaVM, err := o.newVerificationMethod(o.keyAgrType)
if err != nil {
return nil, fmt.Errorf("failed to create new keyagreement VM: %w", err)
}

ka := did.NewReferencedVerification(kaVM, did.KeyAgreement)

// get routers connection ID
routerConnID, err := o.store.Get(connID)
if err != nil && !errors.Is(err, storage.ErrDataNotFound) {
Expand All @@ -145,6 +162,7 @@ func (o *Service) GetDIDDoc(connID string, requiresBlindedRoute bool) (*did.Doc,
ServiceEndpoint: o.endpoint,
}},
VerificationMethod: []did.VerificationMethod{*verMethod},
KeyAgreement: []did.Verification{*ka},
},
)
if errCreate != nil {
Expand All @@ -167,6 +185,7 @@ func (o *Service) GetDIDDoc(connID string, requiresBlindedRoute bool) (*did.Doc,
RoutingKeys: config.Keys(),
}},
VerificationMethod: []did.VerificationMethod{*verMethod},
KeyAgreement: []did.Verification{*ka},
},
)
if err != nil {
Expand All @@ -177,7 +196,10 @@ func (o *Service) GetDIDDoc(connID string, requiresBlindedRoute bool) (*did.Doc,

didSvc, ok := did.LookupService(newDidDoc, didCommServiceType)
if !ok {
return nil, fmt.Errorf("did document missing %s service type", didCommServiceType)
didSvc, ok = did.LookupService(newDidDoc, didCommV2ServiceType)
if !ok {
return nil, fmt.Errorf("did document missing %s service type", didCommServiceType)
}
}

for _, val := range didSvc.RecipientKeys {
Expand All @@ -187,6 +209,18 @@ func (o *Service) GetDIDDoc(connID string, requiresBlindedRoute bool) (*did.Doc,
}
}

for _, kaV := range newDidDoc.KeyAgreement {
kaID := kaV.VerificationMethod.ID
if strings.HasPrefix(kaID, "#") {
kaID = newDidDoc.ID + kaID
}

err = mediatorsvc.AddKeyToRouter(o.mediatorSvc, string(routerConnID), kaID)
if err != nil {
return nil, fmt.Errorf("register did doc keyAgreement key : %w", err)
}
}

return newDidDoc, nil
}

Expand Down Expand Up @@ -237,18 +271,26 @@ func (o *Service) didCommMsgListener(ch <-chan message.Msg) {
}

func (o *Service) handleDIDDocReq(msg service.DIDCommMsg) (service.DIDCommMsgMap, error) {
verMethod, err := o.newVerificationMethod()
verMethod, err := o.newVerificationMethod(kms.ED25519Type)
if err != nil {
return nil, fmt.Errorf("failed to create new verification method: %w", err)
}

kaVM, err := o.newVerificationMethod(o.keyAgrType)
if err != nil {
return nil, fmt.Errorf("failed to create new keyagreement VM: %w", err)
}

ka := did.NewReferencedVerification(kaVM, did.KeyAgreement)

docResolution, err := o.vdriRegistry.Create(
peer.DIDMethod,
&did.Doc{
Service: []did.Service{{
ServiceEndpoint: o.endpoint,
}},
VerificationMethod: []did.VerificationMethod{*verMethod},
KeyAgreement: []did.Verification{*ka},
})
if err != nil {
return nil, fmt.Errorf("failed to create peer did: %w", err)
Expand Down Expand Up @@ -276,21 +318,50 @@ func (o *Service) handleDIDDocReq(msg service.DIDCommMsg) (service.DIDCommMsgMap
}), nil
}

func (o *Service) newVerificationMethod() (*did.VerificationMethod, error) {
// TODO - keytype should be configurable
keyID, pubKeyBytes, err := o.keyManager.CreateAndExportPubKeyBytes(kms.ED25519Type)
const (
ed25519VerificationKey2018 = "Ed25519VerificationKey2018"
x25519KeyAgreementKey2019 = "X25519KeyAgreementKey2019"
jsonWebKey2020 = "JsonWebKey2020"
)

// TODO: copied from hub-router, should push shared code upstream
func (o *Service) newVerificationMethod(kt kms.KeyType) (*did.VerificationMethod, error) {
kid, pkBytes, err := o.keyManager.CreateAndExportPubKeyBytes(kt)
if err != nil {
return nil, fmt.Errorf("kms failed to create public key: %w", err)
return nil, fmt.Errorf("creating public key: %w", err)
}

verMethod := did.NewVerificationMethodFromBytes(
"#"+keyID,
crypto.Ed25519VerificationKey2018,
"",
pubKeyBytes,
)
id := "#" + kid

var vm *did.VerificationMethod

switch kt { // nolint:exhaustive // most cases can use the default.
case kms.ED25519Type:
vm = did.NewVerificationMethodFromBytes(id, ed25519VerificationKey2018, "", pkBytes)
case kms.X25519ECDHKWType:
key := &ariescrypto.PublicKey{}

err = json.Unmarshal(pkBytes, key)
if err != nil {
return nil, fmt.Errorf("unmarshal X25519 key: %w", err)
}

vm = did.NewVerificationMethodFromBytes(id, x25519KeyAgreementKey2019, "", key.X)
default:
j, err := jwkkid.BuildJWK(pkBytes, kt)
if err != nil {
return nil, fmt.Errorf("creating jwk: %w", err)
}

j.KeyID = kid

vm, err = did.NewVerificationMethodFromJWK(id, jsonWebKey2020, "", j)
if err != nil {
return nil, fmt.Errorf("creating verification method: %w", err)
}
}

return verMethod, nil
return vm, nil
}

func (o *Service) handleRouteRegistration(msg message.Msg) (service.DIDCommMsgMap, error) { // nolint: gocyclo,cyclop
Expand Down
Loading

0 comments on commit 71cc3fd

Please sign in to comment.