From 8a09d1e1c0565387820fd4508502d88380703c02 Mon Sep 17 00:00:00 2001 From: Bob Stasyszyn Date: Tue, 6 Feb 2024 09:36:57 -0500 Subject: [PATCH] feat: Add trust-registry option in wallet-cli flows (#1594) Allow to substitute the default trust-registry client. Signed-off-by: Bob Stasyszyn --- .../wallet-cli/pkg/oidc4vci/oidc4vci_flow.go | 25 ++++++++++++++++-- .../wallet-cli/pkg/oidc4vp/oidc4vp_flow.go | 26 ++++++++++++++++--- 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/component/wallet-cli/pkg/oidc4vci/oidc4vci_flow.go b/component/wallet-cli/pkg/oidc4vci/oidc4vci_flow.go index a67e6a569..7918fa8c6 100644 --- a/component/wallet-cli/pkg/oidc4vci/oidc4vci_flow.go +++ b/component/wallet-cli/pkg/oidc4vci/oidc4vci_flow.go @@ -64,6 +64,10 @@ const ( FlowTypePreAuthorizedCode = "pre-authorized_code" ) +type trustRegistry interface { + ValidateIssuer(issuerDID, issuerDomain, credentialType, credentialFormat string, clientAttestationRequested bool) error +} + type Flow struct { httpClient *http.Client documentLoader ld.DocumentLoader @@ -73,6 +77,7 @@ type Flow struct { wallet *wallet.Wallet wellKnownService *wellknown.Service trustRegistryURL string + trustRegistryClient trustRegistry flowType FlowType credentialOffer string credentialType string @@ -188,6 +193,14 @@ func NewFlow(p provider, opts ...Opt) (*Flow, error) { } } + var trustRegistry trustRegistry + + if o.trustRegistry != nil { + trustRegistry = o.trustRegistry + } else if o.trustRegistryURL != "" { + trustRegistry = trustregistry.NewClient(p.HTTPClient(), o.trustRegistryURL) + } + return &Flow{ httpClient: p.HTTPClient(), documentLoader: p.DocumentLoader(), @@ -211,6 +224,7 @@ func NewFlow(p provider, opts ...Opt) (*Flow, error) { issuerState: o.issuerState, pin: o.pin, trustRegistryURL: o.trustRegistryURL, + trustRegistryClient: trustRegistry, perfInfo: &PerfInfo{}, }, nil } @@ -264,7 +278,7 @@ func (f *Flow) Run(ctx context.Context) (*verifiable.Credential, error) { requireWalletAttestation := openIDConfig.TokenEndpointAuthMethodsSupported != nil && lo.Contains(openIDConfig.TokenEndpointAuthMethodsSupported, attestJWTClientAuthType) - if f.trustRegistryURL != "" { + if f.trustRegistryClient != nil { if credentialOfferResponse == nil || len(credentialOfferResponse.Credentials) == 0 { return nil, fmt.Errorf("credential offer is empty") } @@ -290,7 +304,7 @@ func (f *Flow) Run(ctx context.Context) (*verifiable.Credential, error) { credentialFormat := string(credentialOffer.Format) - if err = trustregistry.NewClient(f.httpClient, f.trustRegistryURL). + if err = f.trustRegistryClient. ValidateIssuer( issuerDID, "", @@ -941,6 +955,7 @@ type options struct { issuerState string pin string trustRegistryURL string + trustRegistry trustRegistry walletDIDIndex int } @@ -1030,6 +1045,12 @@ func WithTrustRegistryURL(url string) Opt { } } +func WithTrustRegistry(value trustRegistry) Opt { + return func(opts *options) { + opts.trustRegistry = value + } +} + func WithWalletDIDIndex(idx int) Opt { return func(opts *options) { opts.walletDIDIndex = idx diff --git a/component/wallet-cli/pkg/oidc4vp/oidc4vp_flow.go b/component/wallet-cli/pkg/oidc4vp/oidc4vp_flow.go index ff71b73d2..2efdd3978 100644 --- a/component/wallet-cli/pkg/oidc4vp/oidc4vp_flow.go +++ b/component/wallet-cli/pkg/oidc4vp/oidc4vp_flow.go @@ -53,6 +53,10 @@ const ( customScopeWalletDetails = "walletdetails" ) +type trustRegistry interface { + ValidateVerifier(verifierDID, verifierDomain string, credentials []*verifiable.Credential) error +} + type Flow struct { httpClient *http.Client documentLoader ld.DocumentLoader @@ -67,6 +71,7 @@ type Flow struct { disableSchemaValidation bool trustRegistryURL string perfInfo *PerfInfo + trustRegistryClient trustRegistry } type provider interface { @@ -119,6 +124,14 @@ func NewFlow(p provider, opts ...Opt) (*Flow, error) { kmssigner.NewKMSSigner(signer, signatureType, nil), ) + var trustRegistry trustRegistry + + if o.trustRegistry != nil { + trustRegistry = o.trustRegistry + } else if o.trustRegistryURL != "" { + trustRegistry = trustregistry.NewClient(p.HTTPClient(), o.trustRegistryURL) + } + return &Flow{ httpClient: p.HTTPClient(), documentLoader: p.DocumentLoader(), @@ -131,7 +144,7 @@ func NewFlow(p provider, opts ...Opt) (*Flow, error) { enableLinkedDomainVerification: o.enableLinkedDomainVerification, disableDomainMatching: o.disableDomainMatching, disableSchemaValidation: o.disableSchemaValidation, - trustRegistryURL: o.trustRegistryURL, + trustRegistryClient: trustRegistry, perfInfo: &PerfInfo{}, }, nil } @@ -177,10 +190,10 @@ func (f *Flow) Run(ctx context.Context) error { return fmt.Errorf("query wallet: %w", err) } - if f.trustRegistryURL != "" { + if f.trustRegistryClient != nil { slog.Info("validate verifier", "url", f.trustRegistryURL) - if err = trustregistry.NewClient(f.httpClient, f.trustRegistryURL). + if err = f.trustRegistryClient. ValidateVerifier( requestObject.ClientID, "", @@ -703,6 +716,7 @@ type options struct { disableDomainMatching bool disableSchemaValidation bool trustRegistryURL string + trustRegistry trustRegistry } type Opt func(opts *options) @@ -742,3 +756,9 @@ func WithTrustRegistryURL(url string) Opt { opts.trustRegistryURL = url } } + +func WithTrustRegistry(value trustRegistry) Opt { + return func(opts *options) { + opts.trustRegistry = value + } +}