github.com/hyperledger/aries-framework-go@v0.3.2/pkg/framework/aries/default.go (about)

     1  /*
     2  Copyright SecureKey Technologies Inc. All Rights Reserved.
     3  Copyright Avast Software. All Rights Reserved.
     4  
     5  SPDX-License-Identifier: Apache-2.0
     6  */
     7  
     8  package aries
     9  
    10  import (
    11  	"fmt"
    12  	"net/http"
    13  
    14  	"github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto"
    15  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/dispatcher"
    16  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/packager"
    17  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/packer"
    18  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/packer/anoncrypt"
    19  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/packer/authcrypt"
    20  	legacyAnonCrypt "github.com/hyperledger/aries-framework-go/pkg/didcomm/packer/legacy/anoncrypt"
    21  	legacyAuthCrypt "github.com/hyperledger/aries-framework-go/pkg/didcomm/packer/legacy/authcrypt"
    22  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/didexchange"
    23  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/introduce"
    24  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/issuecredential"
    25  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/legacyconnection"
    26  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/mediator"
    27  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/messagepickup"
    28  	mdissuecredential "github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/middleware/issuecredential"
    29  	mdpresentproof "github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/middleware/presentproof"
    30  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/outofband"
    31  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/outofbandv2"
    32  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/presentproof"
    33  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/transport"
    34  	arieshttp "github.com/hyperledger/aries-framework-go/pkg/didcomm/transport/http"
    35  	"github.com/hyperledger/aries-framework-go/pkg/doc/jose"
    36  	"github.com/hyperledger/aries-framework-go/pkg/framework/aries/api"
    37  	"github.com/hyperledger/aries-framework-go/pkg/framework/context"
    38  	"github.com/hyperledger/aries-framework-go/pkg/kms"
    39  	"github.com/hyperledger/aries-framework-go/pkg/kms/localkms"
    40  	"github.com/hyperledger/aries-framework-go/pkg/secretlock/noop"
    41  	"github.com/hyperledger/aries-framework-go/pkg/store/verifiable"
    42  	"github.com/hyperledger/aries-framework-go/spi/storage"
    43  )
    44  
    45  // defFrameworkOpts provides default framework options.
    46  func defFrameworkOpts(frameworkOpts *Aries) error { //nolint:gocyclo
    47  	// TODO https://github.com/hyperledger/aries-framework-go/issues/209 Move default providers to the sub-package
    48  	if len(frameworkOpts.outboundTransports) == 0 {
    49  		outbound, err := arieshttp.NewOutbound(arieshttp.WithOutboundHTTPClient(&http.Client{}))
    50  		if err != nil {
    51  			return fmt.Errorf("http outbound transport initialization failed: %w", err)
    52  		}
    53  
    54  		frameworkOpts.outboundTransports = append(frameworkOpts.outboundTransports, outbound)
    55  	}
    56  
    57  	if frameworkOpts.storeProvider == nil {
    58  		frameworkOpts.storeProvider = storeProvider()
    59  	}
    60  
    61  	err := createJSONLDContextStore(frameworkOpts)
    62  	if err != nil {
    63  		return err
    64  	}
    65  
    66  	err = createJSONLDRemoteProviderStore(frameworkOpts)
    67  	if err != nil {
    68  		return err
    69  	}
    70  
    71  	err = createJSONLDDocumentLoader(frameworkOpts)
    72  	if err != nil {
    73  		return err
    74  	}
    75  
    76  	err = assignVerifiableStoreIfNeeded(frameworkOpts, frameworkOpts.storeProvider)
    77  	if err != nil {
    78  		return err
    79  	}
    80  
    81  	// order is important:
    82  	// - Route depends on MessagePickup
    83  	// - DIDExchange depends on Route
    84  	// - OutOfBand depends on DIDExchange
    85  	// - Introduce depends on OutOfBand
    86  	frameworkOpts.protocolSvcCreators = append(frameworkOpts.protocolSvcCreators,
    87  		newMessagePickupSvc(), newRouteSvc(), newExchangeSvc(), newLegacyConnectionSvc(), newOutOfBandSvc(),
    88  		newIntroduceSvc(), newIssueCredentialSvc(), newPresentProofSvc(), newOutOfBandV2Svc())
    89  
    90  	if frameworkOpts.secretLock == nil && frameworkOpts.kmsCreator == nil {
    91  		err = createDefSecretLock(frameworkOpts)
    92  		if err != nil {
    93  			return err
    94  		}
    95  	}
    96  
    97  	return setAdditionalDefaultOpts(frameworkOpts)
    98  }
    99  
   100  func newExchangeSvc() api.ProtocolSvcCreator {
   101  	return api.ProtocolSvcCreator{
   102  		Create: func(prv api.Provider) (dispatcher.ProtocolService, error) {
   103  			return &didexchange.Service{}, nil
   104  		},
   105  	}
   106  }
   107  
   108  func newLegacyConnectionSvc() api.ProtocolSvcCreator {
   109  	return api.ProtocolSvcCreator{
   110  		Create: func(prv api.Provider) (dispatcher.ProtocolService, error) {
   111  			return &legacyconnection.Service{}, nil
   112  		},
   113  	}
   114  }
   115  
   116  func newIntroduceSvc() api.ProtocolSvcCreator {
   117  	return api.ProtocolSvcCreator{
   118  		Create: func(prv api.Provider) (dispatcher.ProtocolService, error) {
   119  			return &introduce.Service{}, nil
   120  		},
   121  	}
   122  }
   123  
   124  func newIssueCredentialSvc() api.ProtocolSvcCreator {
   125  	return api.ProtocolSvcCreator{
   126  		Create: func(prv api.Provider) (dispatcher.ProtocolService, error) {
   127  			return &issuecredential.Service{}, nil
   128  		},
   129  		Init: func(svc dispatcher.ProtocolService, prv api.Provider) error {
   130  			icsvc, ok := svc.(*issuecredential.Service)
   131  			if !ok {
   132  				return fmt.Errorf("expected issue credential ProtocolService to be a %T", issuecredential.Service{})
   133  			}
   134  
   135  			err := icsvc.Initialize(prv)
   136  			if err != nil {
   137  				return err
   138  			}
   139  
   140  			// sets default middleware to the service
   141  			icsvc.Use(mdissuecredential.SaveCredentials(prv))
   142  
   143  			return nil
   144  		},
   145  	}
   146  }
   147  
   148  func newPresentProofSvc() api.ProtocolSvcCreator {
   149  	return api.ProtocolSvcCreator{
   150  		Create: func(prv api.Provider) (dispatcher.ProtocolService, error) {
   151  			return &presentproof.Service{}, nil
   152  		},
   153  		Init: func(svc dispatcher.ProtocolService, prv api.Provider) error {
   154  			ppsvc, ok := svc.(*presentproof.Service)
   155  			if !ok {
   156  				return fmt.Errorf("expected present proof ProtocolService to be a %T", presentproof.Service{})
   157  			}
   158  
   159  			err := ppsvc.Initialize(prv)
   160  			if err != nil {
   161  				return err
   162  			}
   163  
   164  			// sets default middleware to the service
   165  			ppsvc.Use(
   166  				mdpresentproof.SavePresentation(prv),
   167  				mdpresentproof.PresentationDefinition(prv,
   168  					mdpresentproof.WithAddProofFn(mdpresentproof.AddBBSProofFn(prv)),
   169  				),
   170  			)
   171  
   172  			return nil
   173  		},
   174  	}
   175  }
   176  
   177  func newRouteSvc() api.ProtocolSvcCreator {
   178  	return api.ProtocolSvcCreator{
   179  		Create: func(prv api.Provider) (dispatcher.ProtocolService, error) {
   180  			return &mediator.Service{}, nil
   181  		},
   182  	}
   183  }
   184  
   185  func newMessagePickupSvc() api.ProtocolSvcCreator {
   186  	return api.ProtocolSvcCreator{
   187  		Create: func(prv api.Provider) (dispatcher.ProtocolService, error) {
   188  			return &messagepickup.Service{}, nil
   189  		},
   190  	}
   191  }
   192  
   193  func newOutOfBandSvc() api.ProtocolSvcCreator {
   194  	return api.ProtocolSvcCreator{
   195  		Create: func(prv api.Provider) (dispatcher.ProtocolService, error) {
   196  			return &outofband.Service{}, nil
   197  		},
   198  	}
   199  }
   200  
   201  func newOutOfBandV2Svc() api.ProtocolSvcCreator {
   202  	return api.ProtocolSvcCreator{
   203  		Create: func(prv api.Provider) (dispatcher.ProtocolService, error) {
   204  			return &outofbandv2.Service{}, nil
   205  		},
   206  		Init: func(svc dispatcher.ProtocolService, prv api.Provider) error {
   207  			oobv2svc, ok := svc.(*outofbandv2.Service)
   208  			if !ok {
   209  				return fmt.Errorf("expected OOB V2 ProtocolService to be a %T", outofbandv2.Service{})
   210  			}
   211  
   212  			err := oobv2svc.Initialize(prv)
   213  			if err != nil {
   214  				return err
   215  			}
   216  
   217  			return nil
   218  		},
   219  	}
   220  }
   221  
   222  func setDefaultKMSCryptOpts(frameworkOpts *Aries) error {
   223  	if frameworkOpts.kmsCreator == nil {
   224  		frameworkOpts.kmsCreator = func(provider kms.Provider) (kms.KeyManager, error) {
   225  			return localkms.New(defaultMasterKeyURI, provider)
   226  		}
   227  	}
   228  
   229  	if frameworkOpts.crypto == nil {
   230  		// create default tink crypto if not passed in frameworkOpts
   231  		cr, err := tinkcrypto.New()
   232  		if err != nil {
   233  			return fmt.Errorf("context creation failed: %w", err)
   234  		}
   235  
   236  		frameworkOpts.crypto = cr
   237  	}
   238  
   239  	return nil
   240  }
   241  
   242  func setAdditionalDefaultOpts(frameworkOpts *Aries) error {
   243  	err := setDefaultKMSCryptOpts(frameworkOpts)
   244  	if err != nil {
   245  		return err
   246  	}
   247  
   248  	if frameworkOpts.keyType == "" {
   249  		frameworkOpts.keyType = kms.ED25519Type
   250  	}
   251  
   252  	if frameworkOpts.keyAgreementType == "" {
   253  		frameworkOpts.keyAgreementType = kms.X25519ECDHKWType
   254  	}
   255  
   256  	if frameworkOpts.packerCreator == nil {
   257  		frameworkOpts.packerCreator = func(provider packer.Provider) (packer.Packer, error) {
   258  			return legacyAuthCrypt.New(provider), nil
   259  		}
   260  
   261  		frameworkOpts.packerCreators = []packer.Creator{
   262  			func(provider packer.Provider) (packer.Packer, error) {
   263  				return legacyAuthCrypt.New(provider), nil
   264  			},
   265  			func(provider packer.Provider) (packer.Packer, error) {
   266  				return legacyAnonCrypt.New(provider), nil
   267  			},
   268  
   269  			func(provider packer.Provider) (packer.Packer, error) {
   270  				return authcrypt.New(provider, jose.A256CBCHS512)
   271  			},
   272  			func(provider packer.Provider) (packer.Packer, error) {
   273  				return anoncrypt.New(provider, jose.A256GCM)
   274  			},
   275  		}
   276  	}
   277  
   278  	if frameworkOpts.packagerCreator == nil {
   279  		frameworkOpts.packagerCreator = func(prov packager.Provider) (transport.Packager, error) {
   280  			return packager.New(prov)
   281  		}
   282  	}
   283  
   284  	if frameworkOpts.protocolStateStoreProvider == nil {
   285  		frameworkOpts.protocolStateStoreProvider = storeProvider()
   286  	}
   287  
   288  	if frameworkOpts.msgSvcProvider == nil {
   289  		frameworkOpts.msgSvcProvider = &noOpMessageServiceProvider{}
   290  	}
   291  
   292  	if frameworkOpts.mediaTypeProfiles == nil {
   293  		// For now only set legacy media type profile to match default key type and primary packer above.
   294  		// Using media type profile, not just a media type, in order to align with OOB invitations' Accept header.
   295  		// TODO once keyAgreement is added in the packers, this can be switched to DIDcomm V2 media type as well as
   296  		// 		switching legacyPacker with authcrtypt as primary packer and using an ECDH-1PU key as default key above.
   297  		frameworkOpts.mediaTypeProfiles = []string{transport.MediaTypeAIP2RFC0019Profile}
   298  	}
   299  
   300  	return nil
   301  }
   302  
   303  func assignVerifiableStoreIfNeeded(aries *Aries, storeProvider storage.Provider) error {
   304  	if aries.verifiableStore != nil {
   305  		return nil
   306  	}
   307  
   308  	provider, err := context.New(
   309  		context.WithStorageProvider(storeProvider),
   310  		context.WithJSONLDDocumentLoader(aries.documentLoader),
   311  	)
   312  	if err != nil {
   313  		return fmt.Errorf("verifiable store initialization failed : %w", err)
   314  	}
   315  
   316  	aries.verifiableStore, err = verifiable.New(provider)
   317  	if err != nil {
   318  		return fmt.Errorf("can't initialize verifaible store : %w", err)
   319  	}
   320  
   321  	return nil
   322  }
   323  
   324  func createDefSecretLock(opts *Aries) error {
   325  	// default lock is noop, ie keys are not secure by default.
   326  	// users of the framework must pre-build a secure lock and pass it in as an option
   327  	opts.secretLock = &noop.NoLock{}
   328  
   329  	return nil
   330  }
   331  
   332  // noOpMessageServiceProvider returns noop message service provider.
   333  type noOpMessageServiceProvider struct{}
   334  
   335  // Services returns empty list of services for noOpMessageServiceProvider.
   336  func (n *noOpMessageServiceProvider) Services() []dispatcher.MessageService {
   337  	return []dispatcher.MessageService{}
   338  }