diff --git a/demo/app/lib/scenarios/handle_openid_vp_flow.dart b/demo/app/lib/scenarios/handle_openid_vp_flow.dart index fed7cc45..9aa6dc08 100644 --- a/demo/app/lib/scenarios/handle_openid_vp_flow.dart +++ b/demo/app/lib/scenarios/handle_openid_vp_flow.dart @@ -5,6 +5,7 @@ SPDX-License-Identifier: Apache-2.0 */ import 'dart:developer'; +import 'dart:convert'; import 'package:app/wallet_sdk/wallet_sdk.dart'; import 'package:app/views/custom_error.dart'; import 'package:flutter/material.dart'; @@ -51,8 +52,24 @@ void handleOpenIDVpFlow(BuildContext context, String qrCodeURL) async { for (var cred in credentials) { log('multi cred flow $submission and ${credentials.length}'); for (var inputDescriptor in submission.inputDescriptors) { - Map payload = Jwt.parseJwt(cred); - if (inputDescriptor.matchedVCsID.contains(payload['jti'])) { + Map? payload; + try { + payload = Jwt.parseJwt(cred); + } catch (jwtError) { + try { + payload = json.decode(cred) as Map; + } catch (jsonError) { + log('error while parsing cred as json: $jsonError'); + continue; + } + } + var key = payload['jti'] ?? payload['id']; + if (key == null) { + log('no key found in cred payload'); + continue; + } + if (inputDescriptor.matchedVCsID.contains(key)) { + log('matched vc with id $key added to list'); var credentialDisplayData = storedCredentials .where((element) => cred.contains(element.value.rawCredential)) .map((e) => e.value) diff --git a/pkg/ldproof/ldproof.go b/pkg/ldproof/ldproof.go new file mode 100644 index 00000000..a980726b --- /dev/null +++ b/pkg/ldproof/ldproof.go @@ -0,0 +1,196 @@ +/* +Copyright Gen Digital Inc. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package ldproof + +import ( + "crypto" + "encoding/base64" + "fmt" + + "github.com/piprate/json-gold/ld" + diddoc "github.com/trustbloc/did-go/doc/did" + "github.com/trustbloc/did-go/doc/ld/processor" + "github.com/trustbloc/kms-go/spi/kms" + "github.com/trustbloc/vc-go/presexch" + "github.com/trustbloc/vc-go/proof" + "github.com/trustbloc/vc-go/proof/creator" + "github.com/trustbloc/vc-go/proof/ldproofs/ecdsasecp256k1signature2019" + "github.com/trustbloc/vc-go/proof/ldproofs/ed25519signature2018" + "github.com/trustbloc/vc-go/proof/ldproofs/ed25519signature2020" + "github.com/trustbloc/vc-go/proof/ldproofs/jsonwebsignature2020" + "github.com/trustbloc/vc-go/verifiable" + + "github.com/trustbloc/wallet-sdk/pkg/api" +) + +const ( + proofPurpose = "authentication" +) + +var supportedLDProofTypes = map[string]proof.LDProofDescriptor{ + ecdsasecp256k1signature2019.ProofType: ecdsasecp256k1signature2019.New(), + ed25519signature2018.ProofType: ed25519signature2018.New(), + ed25519signature2020.ProofType: ed25519signature2020.New(), + jsonwebsignature2020.ProofType: jsonwebsignature2020.New(), +} + +// LDProof implements functionality of adding linked data proof to the verifiable presentation. +type LDProof struct { + crypto api.Crypto + documentLoader ld.DocumentLoader + ldProofDescriptor proof.LDProofDescriptor + keyType kms.KeyType +} + +// New returns a new instance of LDProof. +func New( + crypto api.Crypto, + documentLoader ld.DocumentLoader, + ldpVPFormat *presexch.LdpType, + keyType kms.KeyType, +) (*LDProof, error) { + var ( + proofDesc proof.LDProofDescriptor + found bool + ) + + for _, proofType := range ldpVPFormat.ProofType { + if proofDesc, found = supportedLDProofTypes[proofType]; found && isKeyTypeSupported(proofDesc, keyType) { + break + } + found = false + } + + if !found { + return nil, fmt.Errorf("no supported linked data proof found") + } + + return &LDProof{ + crypto: crypto, + documentLoader: documentLoader, + ldProofDescriptor: proofDesc, + keyType: keyType, + }, nil +} + +func isKeyTypeSupported(ldProof proof.LDProofDescriptor, keyType kms.KeyType) bool { + for _, vm := range ldProof.SupportedVerificationMethods() { + if vm.KMSKeyType == keyType { + return true + } + } + + return false +} + +// Add adds linked data proof to the verifiable presentation. +func (p *LDProof) Add(vp *verifiable.Presentation, opts ...Opt) error { + o := &options{} + + for _, opt := range opts { + opt(o) + } + + if err := p.validateSigningVerificationMethod(o); err != nil { + return err + } + + signer, err := p.createSigner(o) + if err != nil { + return err + } + + p.updatePresentationContext(vp) + + proofContext := &verifiable.LinkedDataProofContext{ + SignatureType: p.ldProofDescriptor.ProofType(), + ProofCreator: creator.New(creator.WithLDProofType(p.ldProofDescriptor, signer)), + KeyType: p.keyType, + SignatureRepresentation: verifiable.SignatureProofValue, + VerificationMethod: o.signingVM.ID, + Challenge: o.nonce, + Domain: o.domain, + Purpose: proofPurpose, + } + + return vp.AddLinkedDataProof( + proofContext, + processor.WithDocumentLoader(p.documentLoader), + ) +} + +func (p *LDProof) validateSigningVerificationMethod(opts *options) error { + if opts.signingVM == nil { + return fmt.Errorf("missing signing verification method") + } + + if jwk := opts.signingVM.JSONWebKey(); jwk == nil { + return fmt.Errorf("missing jwk for %s verification method", opts.signingVM.ID) + } + + return nil +} + +func (p *LDProof) createSigner(opts *options) (*cryptoSigner, error) { + jwk := opts.signingVM.JSONWebKey() + + tb, err := jwk.Thumbprint(crypto.SHA256) + if err != nil { + return nil, fmt.Errorf("create crypto thumbprint for jwk: %w", err) + } + + return &cryptoSigner{ + crypto: p.crypto, + keyID: base64.RawURLEncoding.EncodeToString(tb), + }, nil +} + +func (p *LDProof) updatePresentationContext(vp *verifiable.Presentation) { + vp.Context = append(vp.Context, + "https://www.w3.org/ns/credentials/examples/v2", + "https://w3c-ccg.github.io/lds-jws2020/contexts/lds-jws2020-v1.json", + ) +} + +type options struct { + signingVM *diddoc.VerificationMethod + nonce string + domain string +} + +// Opt is an option for adding linked data proof. +type Opt func(opts *options) + +// WithSigningVM sets signing verification method. +func WithSigningVM(vm *diddoc.VerificationMethod) Opt { + return func(opts *options) { + opts.signingVM = vm + } +} + +// WithNonce sets nonce. +func WithNonce(nonce string) Opt { + return func(opts *options) { + opts.nonce = nonce + } +} + +// WithDomain sets domain. +func WithDomain(domain string) Opt { + return func(opts *options) { + opts.domain = domain + } +} + +type cryptoSigner struct { + crypto api.Crypto + keyID string +} + +func (s *cryptoSigner) Sign(data []byte) ([]byte, error) { + return s.crypto.Sign(data, s.keyID) +} diff --git a/pkg/ldproof/ldproof_test.go b/pkg/ldproof/ldproof_test.go new file mode 100644 index 00000000..939efb8f --- /dev/null +++ b/pkg/ldproof/ldproof_test.go @@ -0,0 +1,183 @@ +/* +Copyright Gen Digital Inc. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package ldproof_test + +import ( + "crypto/ed25519" + "crypto/rand" + "testing" + + "github.com/piprate/json-gold/ld" + "github.com/stretchr/testify/require" + diddoc "github.com/trustbloc/did-go/doc/did" + "github.com/trustbloc/kms-go/doc/util/jwkkid" + "github.com/trustbloc/kms-go/spi/kms" + "github.com/trustbloc/vc-go/presexch" + "github.com/trustbloc/vc-go/verifiable" + + "github.com/trustbloc/wallet-sdk/internal/testutil" + "github.com/trustbloc/wallet-sdk/pkg/api" + "github.com/trustbloc/wallet-sdk/pkg/ldproof" +) + +func TestNew(t *testing.T) { + var ( + crypto api.Crypto + documentLoader ld.DocumentLoader + ldpVPFormat *presexch.LdpType + keyType kms.KeyType + ) + + tests := []struct { + name string + setup func() + check func(t *testing.T, ldProof *ldproof.LDProof, err error) + }{ + { + name: "success", + setup: func() { + crypto = &cryptoMock{} + documentLoader = testutil.DocumentLoader(t) + ldpVPFormat = &presexch.LdpType{ + ProofType: []string{"EcdsaSecp256k1Signature2019", "Ed25519Signature2018", "Ed25519Signature2020", + "JsonWebSignature2020", + }, + } + keyType = kms.ECDSAP384IEEEP1363 + }, + check: func(t *testing.T, ldProof *ldproof.LDProof, err error) { + require.NotNil(t, ldProof) + require.NoError(t, err) + }, + }, + { + name: "no supported linked data proof found", + setup: func() { + documentLoader = testutil.DocumentLoader(t) + ldpVPFormat = &presexch.LdpType{ + ProofType: []string{"Ed25519Signature2018", "Ed25519Signature2020"}, + } + keyType = kms.ECDSAP384IEEEP1363 + }, + check: func(t *testing.T, ldProof *ldproof.LDProof, err error) { + require.Nil(t, ldProof) + require.ErrorContains(t, err, "no supported linked data proof found") + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tt.setup() + + ldProof, err := ldproof.New(crypto, documentLoader, ldpVPFormat, keyType) + tt.check(t, ldProof, err) + }) + } +} + +func TestLDProof_Add(t *testing.T) { + ldProof, err := ldproof.New( + &cryptoMock{Signature: []byte("signature")}, + testutil.DocumentLoader(t), + &presexch.LdpType{ + ProofType: []string{"EcdsaSecp256k1Signature2019", "Ed25519Signature2018", "Ed25519Signature2020", + "JsonWebSignature2020", + }, + }, + kms.ED25519Type, + ) + require.NoError(t, err) + + verKey, _, err := ed25519.GenerateKey(rand.Reader) + require.NoError(t, err) + + jwk, err := jwkkid.BuildJWK(verKey, kms.ED25519Type) + require.NoError(t, err) + + var ( + vp *verifiable.Presentation + opts []ldproof.Opt + ) + + tests := []struct { + name string + setup func() + check func(t *testing.T, err error) + }{ + { + name: "success", + setup: func() { + vp = &verifiable.Presentation{} + + var signingVM *diddoc.VerificationMethod + + signingVM, err = diddoc.NewVerificationMethodFromJWK("vmID", "Ed25519VerificationKey2018", "", jwk) + require.NoError(t, err) + + opts = []ldproof.Opt{ + ldproof.WithSigningVM(signingVM), + ldproof.WithNonce("nonce"), + ldproof.WithDomain("example.com"), + } + }, + check: func(t *testing.T, err error) { + require.NoError(t, err) + }, + }, + { + name: "missing signing verification method", + setup: func() { + vp = &verifiable.Presentation{} + + opts = []ldproof.Opt{ + ldproof.WithNonce("nonce"), + ldproof.WithDomain("example.com"), + } + }, + check: func(t *testing.T, err error) { + require.ErrorContains(t, err, "missing signing verification method") + }, + }, + { + name: "missing jwk for verification method", + setup: func() { + vp = &verifiable.Presentation{} + + signingVM := &diddoc.VerificationMethod{ + ID: "vmID", + Type: "Ed25519VerificationKey2018", + } + + opts = []ldproof.Opt{ + ldproof.WithSigningVM(signingVM), + ldproof.WithNonce("nonce"), + ldproof.WithDomain("example.com"), + } + }, + check: func(t *testing.T, err error) { + require.ErrorContains(t, err, "missing jwk for vmID verification method") + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tt.setup() + + err = ldProof.Add(vp, opts...) + tt.check(t, err) + }) + } +} + +type cryptoMock struct { + Signature []byte + Err error +} + +func (c *cryptoMock) Sign([]byte, string) ([]byte, error) { + return c.Signature, c.Err +} diff --git a/pkg/openid4vp/openid4vp.go b/pkg/openid4vp/openid4vp.go index cbd75628..cee3de16 100644 --- a/pkg/openid4vp/openid4vp.go +++ b/pkg/openid4vp/openid4vp.go @@ -26,6 +26,7 @@ import ( "github.com/trustbloc/bbs-signature-go/bbs12381g2pub" diddoc "github.com/trustbloc/did-go/doc/did" vdrapi "github.com/trustbloc/did-go/vdr/api" + "github.com/trustbloc/kms-go/spi/kms" wrapperapi "github.com/trustbloc/kms-go/wrapper/api" "github.com/trustbloc/vc-go/dataintegrity" "github.com/trustbloc/vc-go/dataintegrity/suite/ecdsa2019" @@ -33,6 +34,7 @@ import ( "github.com/trustbloc/vc-go/presexch" "github.com/trustbloc/vc-go/proof/defaults" "github.com/trustbloc/vc-go/verifiable" + "github.com/trustbloc/wallet-sdk/pkg/ldproof" "github.com/trustbloc/wallet-sdk/pkg/api" "github.com/trustbloc/wallet-sdk/pkg/common" @@ -86,7 +88,7 @@ type Interaction struct { type authorizedResponse struct { IDTokenJWS string - VPTokenJWS string + VPToken string PresentationSubmission string State string } @@ -285,7 +287,7 @@ func (o *Interaction) presentCredentials( data := url.Values{} data.Set("id_token", response.IDTokenJWS) - data.Set("vp_token", response.VPTokenJWS) + data.Set("vp_token", response.VPToken) data.Set("presentation_submission", response.PresentationSubmission) data.Set("state", response.State) @@ -488,6 +490,17 @@ func createAuthorizedResponseOneCred( //nolint:funlen,gocyclo // Unable to decom VerificationMethodResolver: common.NewVDRKeyResolver(didResolver), } + vpFormat := presexch.FormatJWTVP + + if vpFormats := requestObject.ClientMetadata.VPFormats; vpFormats != nil { + switch { + case vpFormats.JwtVP != nil: + break + case vpFormats.LdpVP != nil: + vpFormat = presexch.FormatLDPVP + } + } + presentation, err := pd.CreateVP( []*verifiable.Credential{credential}, documentLoader, @@ -497,7 +510,7 @@ func createAuthorizedResponseOneCred( //nolint:funlen,gocyclo // Unable to decom verifiable.WithJSONLDDocumentLoader(documentLoader), verifiable.WithProofChecker(defaults.NewDefaultProofChecker(common.NewVDRKeyResolver(didResolver))), ), - presexch.WithDefaultPresentationFormat(presexch.FormatJWTVP), + presexch.WithDefaultPresentationFormat(vpFormat), ) if err != nil { return nil, err @@ -552,20 +565,32 @@ func createAuthorizedResponseOneCred( //nolint:funlen,gocyclo // Unable to decom return nil, err } - vpTok := vpTokenClaims{ - VP: presentation, - Nonce: requestObject.Nonce, - Exp: time.Now().Unix() + tokenLiveTimeSec, - Iss: did, - Aud: requestObject.ClientID, - Nbf: time.Now().Unix(), - Iat: time.Now().Unix(), - Jti: uuid.NewString(), - } + var vpToken string - vpTokenJWS, err := signToken(vpTok, jwtSigner) - if err != nil { - return nil, fmt.Errorf("sign vp_token: %w", err) + switch vpFormat { + case presexch.FormatJWTVP: + claims := vpTokenClaims{ + VP: presentation, + Nonce: requestObject.Nonce, + Exp: time.Now().Unix() + tokenLiveTimeSec, + Iss: did, + Aud: requestObject.ClientID, + Nbf: time.Now().Unix(), + Iat: time.Now().Unix(), + Jti: uuid.NewString(), + } + + vpToken, err = signToken(claims, jwtSigner) + if err != nil { + return nil, fmt.Errorf("sign vp token: %w", err) + } + case presexch.FormatLDPVP: + vpToken, err = createLdpVPToken(crypto, documentLoader, signingVM, requestObject, presentation) + if err != nil { + return nil, fmt.Errorf("create ldp vp token: %w", err) + } + default: + return nil, fmt.Errorf("unsupported presentation exchange format: %s", vpFormat) } presentationSubmissionBytes, err := json.Marshal(presentationSubmission) @@ -575,7 +600,7 @@ func createAuthorizedResponseOneCred( //nolint:funlen,gocyclo // Unable to decom return &authorizedResponse{ IDTokenJWS: idTokenJWS, - VPTokenJWS: vpTokenJWS, + VPToken: vpToken, PresentationSubmission: string(presentationSubmissionBytes), State: requestObject.State, }, nil @@ -598,6 +623,17 @@ func createAuthorizedResponseMultiCred( //nolint:funlen,gocyclo // Unable to dec VerificationMethodResolver: common.NewVDRKeyResolver(didResolver), } + vpFormat := presexch.FormatJWTVP + + if vpFormats := requestObject.ClientMetadata.VPFormats; vpFormats != nil { + switch { + case vpFormats.JwtVP != nil: + break + case vpFormats.LdpVP != nil: + vpFormat = presexch.FormatLDPVP + } + } + presentations, presentationSubmission, err := pd.CreateVPArray( credentials, documentLoader, @@ -606,7 +642,7 @@ func createAuthorizedResponseMultiCred( //nolint:funlen,gocyclo // Unable to dec verifiable.WithDisabledProofCheck(), verifiable.WithJSONLDDocumentLoader(documentLoader), ), - presexch.WithDefaultPresentationFormat(presexch.FormatJWTVP), + presexch.WithDefaultPresentationFormat(vpFormat), ) if err != nil { return nil, err @@ -640,31 +676,43 @@ func createAuthorizedResponseMultiCred( //nolint:funlen,gocyclo // Unable to dec } } - signer, e := getHolderSigner(signingVM, crypto) + jwtSigner, e := getHolderSigner(signingVM, crypto) if e != nil { return nil, e } - signers[holderDID] = signer - - // TODO: Fix this issue: the vpToken always uses the last presentation from the loop above - vpTok := vpTokenClaims{ - VP: presentation, - Nonce: requestObject.Nonce, - Exp: time.Now().Unix() + tokenLiveTimeSec, - Iss: holderDID, - Aud: requestObject.ClientID, - Nbf: time.Now().Unix(), - Iat: time.Now().Unix(), - Jti: uuid.NewString(), - } + signers[holderDID] = jwtSigner + + var vpToken string + + switch vpFormat { + case presexch.FormatJWTVP: + // TODO: Fix this issue: the vpToken always uses the last presentation from the loop above + claims := vpTokenClaims{ + VP: presentation, + Nonce: requestObject.Nonce, + Exp: time.Now().Unix() + tokenLiveTimeSec, + Iss: holderDID, + Aud: requestObject.ClientID, + Nbf: time.Now().Unix(), + Iat: time.Now().Unix(), + Jti: uuid.NewString(), + } - vpTokJWS, e := signToken(vpTok, signer) - if e != nil { - return nil, fmt.Errorf("sign vp_token: %w", e) + vpToken, err = signToken(claims, jwtSigner) + if err != nil { + return nil, fmt.Errorf("sign vp token: %w", err) + } + case presexch.FormatLDPVP: + vpToken, err = createLdpVPToken(crypto, documentLoader, signingVM, requestObject, presentation) + if err != nil { + return nil, fmt.Errorf("create ldp vp token: %w", err) + } + default: + return nil, fmt.Errorf("unsupported presentation exchange format: %s", vpFormat) } - vpTokens = append(vpTokens, vpTokJWS) + vpTokens = append(vpTokens, vpToken) } vpTokenListJSON, err := json.Marshal(vpTokens) @@ -699,7 +747,7 @@ func createAuthorizedResponseMultiCred( //nolint:funlen,gocyclo // Unable to dec return &authorizedResponse{ IDTokenJWS: idTokenJWS, - VPTokenJWS: string(vpTokenListJSON), + VPToken: string(vpTokenListJSON), PresentationSubmission: string(presentationSubmissionJSON), State: requestObject.State, }, nil @@ -708,7 +756,7 @@ func createAuthorizedResponseMultiCred( //nolint:funlen,gocyclo // Unable to dec func addDataIntegrityProof(did string, didResolver api.DIDResolver, documentLoader ld.DocumentLoader, signer wrapperapi.KMSCryptoSigner, presentation *verifiable.Presentation, ) error { - context := &verifiable.DataIntegrityProofContext{ + proofContext := &verifiable.DataIntegrityProofContext{ SigningKeyID: did, CryptoSuite: ecdsa2019.SuiteType, } @@ -724,7 +772,7 @@ func addDataIntegrityProof(did string, didResolver api.DIDResolver, documentLoad return err } - err = presentation.AddDataIntegrityProof(context, dataIntegritySigner) + err = presentation.AddDataIntegrityProof(proofContext, dataIntegritySigner) if err != nil { return err } @@ -732,6 +780,43 @@ func addDataIntegrityProof(did string, didResolver api.DIDResolver, documentLoad return nil } +func createLdpVPToken( + crypto api.Crypto, + documentLoader ld.DocumentLoader, + signingVM *diddoc.VerificationMethod, + requestObject *requestObject, + presentation *verifiable.Presentation, +) (string, error) { + ldProof, err := ldproof.New( + crypto, + documentLoader, + requestObject.ClientMetadata.VPFormats.LdpVP, + kms.ECDSAP384IEEEP1363, // TODO: Use the key type passed from the caller + ) + if err != nil { + return "", fmt.Errorf("create ld proof: %w", err) + } + + err = ldProof.Add( + presentation, + ldproof.WithSigningVM(signingVM), + ldproof.WithNonce(requestObject.Nonce), + ldproof.WithDomain(requestObject.ClientID), + ) + if err != nil { + return "", fmt.Errorf("add ld proof to vp: %w", err) + } + + var vpBytes []byte + + vpBytes, err = presentation.MarshalJSON() + if err != nil { + return "", fmt.Errorf("marshal vp into vp token: %w", err) + } + + return string(vpBytes), nil +} + func createIDToken( req *requestObject, signingDID string, diff --git a/pkg/openid4vp/openid4vp_test.go b/pkg/openid4vp/openid4vp_test.go index d1393b32..822a3852 100644 --- a/pkg/openid4vp/openid4vp_test.go +++ b/pkg/openid4vp/openid4vp_test.go @@ -24,6 +24,9 @@ import ( "github.com/trustbloc/did-go/doc/did" "github.com/trustbloc/did-go/doc/did/endpoint" "github.com/trustbloc/kms-go/doc/jose" + "github.com/trustbloc/kms-go/doc/jose/jwk" + "github.com/trustbloc/kms-go/doc/util/jwkkid" + "github.com/trustbloc/kms-go/spi/kms" "github.com/trustbloc/vc-go/presexch" "github.com/trustbloc/vc-go/verifiable" @@ -40,6 +43,9 @@ var ( //go:embed test_data/request_object.jwt requestObjectJWT string + //go:embed test_data/request_object_ldp_vp.jwt + requestObjectJWTLdpVP string + //go:embed test_data/presentation.jsonld presentationJSONLD []byte @@ -213,7 +219,7 @@ func TestOpenID4VP_PresentCredential(t *testing.T) { singleCred = append(singleCred, credentials[0]) - mockDoc := mockResolution(t, mockDID) + mockDoc := mockResolution(t, mockDID, false) mockPresentationDefinition := &presexch.PresentationDefinition{ ID: uuid.NewString(), @@ -421,6 +427,42 @@ func TestOpenID4VP_PresentCredential(t *testing.T) { require.NoError(t, err) }) + t.Run("Success - with ldp_vp", func(t *testing.T) { + mockHTTPClient := &mock.HTTPClientMock{ + StatusCode: 200, + } + + crypto := &cryptoMock{SignVal: []byte(testSignature)} + + interaction, err := NewInteraction( + requestObjectJWTLdpVP, + &jwtSignatureVerifierMock{}, + &didResolverMock{ResolveValue: mockResolution(t, mockDID, true)}, + crypto, + lddl, + WithHTTPClient(mockHTTPClient), + ) + require.NoError(t, err) + + query := interaction.GetQuery() + require.NotNil(t, query) + + err = interaction.PresentCredential(singleCred, CustomClaims{}) + require.NoError(t, err) + + data, err := url.ParseQuery(string(mockHTTPClient.SentBody)) + require.NoError(t, err) + + require.Contains(t, data, "id_token") + require.NotEmpty(t, data["id_token"]) + + require.Contains(t, data, "vp_token") + require.NotEmpty(t, data["vp_token"]) + + require.Contains(t, data, "presentation_submission") + require.NotEmpty(t, data["presentation_submission"]) + }) + t.Run("Check custom claims", func(t *testing.T) { response, err := createAuthorizedResponse( singleCred, @@ -460,7 +502,7 @@ func TestOpenID4VP_PresentCredential(t *testing.T) { require.NoError(t, err) require.Contains(t, string(idToken), "test123456") - vpToken, err := base64.RawURLEncoding.DecodeString(strings.Split(response.VPTokenJWS, ".")[1]) + vpToken, err := base64.RawURLEncoding.DecodeString(strings.Split(response.VPToken, ".")[1]) require.NoError(t, err) require.Contains(t, string(vpToken), "test123456") }) @@ -916,7 +958,7 @@ func TestInteraction_Scope(t *testing.T) { } func TestResolverAdapter(t *testing.T) { - mockDoc := mockResolution(t, mockDID) + mockDoc := mockResolution(t, mockDID, false) adapter := wrapResolver(&didResolverMock{ResolveValue: mockDoc}) doc, err := adapter.Resolve(mockDID) @@ -953,7 +995,7 @@ func TestOpenID4VP_PresentedClaims(t *testing.T) { singleCred = append(singleCred, credentials[0]) - mockDoc := mockResolution(t, mockDID) + mockDoc := mockResolution(t, mockDID, false) t.Run("Success", func(t *testing.T) { httpClient := &mock.HTTPClientMock{ @@ -1163,13 +1205,25 @@ func (c *cryptoMock) Verify(_, _ []byte, _ string) error { return c.VerifyErr } -func mockResolution(t *testing.T, mockDID string) *did.DocResolution { +func mockResolution(t *testing.T, mockDID string, useJWK bool) *did.DocResolution { t.Helper() edPub, _, err := ed25519.GenerateKey(rand.Reader) require.NoError(t, err) - mockVM := did.NewVerificationMethodFromBytes(mockVMID, "Ed25519VerificationKey2018", mockDID, edPub) + var mockVM *did.VerificationMethod + + if useJWK { + var key *jwk.JWK + + key, err = jwkkid.BuildJWK(edPub, kms.ED25519Type) + require.NoError(t, err) + + mockVM, err = did.NewVerificationMethodFromJWK(mockVMID, "JsonWebKey2020", mockDID, key) + require.NoError(t, err) + } else { + mockVM = did.NewVerificationMethodFromBytes(mockVMID, "Ed25519VerificationKey2018", mockDID, edPub) + } docRes := &did.DocResolution{ DIDDocument: &did.Doc{ diff --git a/pkg/openid4vp/request_object.go b/pkg/openid4vp/request_object.go index af92a8ef..c940f8a7 100644 --- a/pkg/openid4vp/request_object.go +++ b/pkg/openid4vp/request_object.go @@ -49,9 +49,7 @@ type requestObjectRegistration struct { } type requestObjectClaims struct { - VPToken vpToken `json:"vp_token"` -} - -type vpToken struct { - PresentationDefinition *presexch.PresentationDefinition `json:"presentation_definition"` + VPToken struct { + PresentationDefinition *presexch.PresentationDefinition `json:"presentation_definition"` + } `json:"vp_token"` } diff --git a/pkg/openid4vp/test_data/request_object_ldp_vp.jwt b/pkg/openid4vp/test_data/request_object_ldp_vp.jwt new file mode 100644 index 00000000..e321a306 --- /dev/null +++ b/pkg/openid4vp/test_data/request_object_ldp_vp.jwt @@ -0,0 +1 @@ +eyJhbGciOiJFZERTQSIsImtpZCI6ImRpZDppb246RWlDZ3hETFJjTmpzZ1lHWVd5UHRvZXJnVTNuUGo4UnFlck1XVzE0TGE3V2FQZzpleUprWld4MFlTSTZleUp3WVhSamFHVnpJanBiZXlKaFkzUnBiMjRpT2lKaFpHUXRjSFZpYkdsakxXdGxlWE1pTENKd2RXSnNhV05MWlhseklqcGJleUpwWkNJNklrZFNYemRCVEhSQ05rWjRUM3B6ZWsxeWEyTmZNVFZCWW1kbFJEaDZiVGxCYVVwWGN6VlpObk5xZERnaUxDSndkV0pzYVdOTFpYbEtkMnNpT25zaVkzSjJJam9pUldReU5UVXhPU0lzSW10cFpDSTZJa2RTWHpkQlRIUkNOa1o0VDNwemVrMXlhMk5mTVRWQlltZGxSRGg2YlRsQmFVcFhjelZaTm5OcWREZ2lMQ0pyZEhraU9pSlBTMUFpTENKNElqb2lSMjFOY1dSaGNWaFpTMmhDTTFwNkxXdzVhRTlDYlhobFowaFNOMUF4UVdsTFZ5MVlaVWROTUd4dFp5SjlMQ0p3ZFhKd2IzTmxjeUk2V3lKaGRYUm9aVzUwYVdOaGRHbHZiaUlzSW1GemMyVnlkR2x2YmsxbGRHaHZaQ0pkTENKMGVYQmxJam9pUldReU5UVXhPVlpsY21sbWFXTmhkR2x2Ymt0bGVUSXdNVGdpZlYxOUxIc2lZV04wYVc5dUlqb2lZV1JrTFhObGNuWnBZMlZ6SWl3aWMyVnlkbWxqWlhNaU9sdDdJbWxrSWpvaVRHbHVhMlZrUkc5dFlXbHVjeUlzSW5ObGNuWnBZMlZGYm1Sd2IybHVkQ0k2ZXlKdmNtbG5hVzV6SWpwYkltaDBkSEE2THk5MlkzTXVkMlZpYUc5dmF5NWxlR0Z0Y0d4bExtTnZiVG80TVRnd0x5SmRmU3dpZEhsd1pTSTZJa3hwYm10bFpFUnZiV0ZwYm5NaWZWMTlYU3dpZFhCa1lYUmxRMjl0YldsMGJXVnVkQ0k2SWtWcFFqbHlZWE42UjBOalVtVnVSVTQzTUVoMlN6bE5kbDlpVEVseVdXWmtVbVZUZGs5VlRubHpabkY1YmxFaWZTd2ljM1ZtWm1sNFJHRjBZU0k2ZXlKa1pXeDBZVWhoYzJnaU9pSkZhVVIxVGpSa2JGOUlTMWhZYlVOTmFHNWphR3MxYW5nelFVcG5abXR6ZW1oS1UxQnlObGRuYkdkamJWUlJJaXdpY21WamIzWmxjbmxEYjIxdGFYUnRaVzUwSWpvaVJXbEJOVFpyUlZaekxURkVZMDlJYzNkcllWSmlTazVZVlc1Tk1tWnVaWGxyWm5SUFRVZGFiWFowTlZrd2R5SjlMQ0owZVhCbElqb2lZM0psWVhSbEluMCNHUl83QUx0QjZGeE96c3pNcmtjXzE1QWJnZUQ4em05QWlKV3M1WTZzanQ4In0.eyJjbGFpbXMiOnsidnBfdG9rZW4iOnsicHJlc2VudGF0aW9uX2RlZmluaXRpb24iOnsiZm9ybWF0Ijp7ImxkcCI6eyJwcm9vZl90eXBlIjpbIkpzb25XZWJTaWduYXR1cmUyMDIwIiwiRWQyNTUxOVNpZ25hdHVyZTIwMTgiLCJFY2RzYVNlY3AyNTZrMVNpZ25hdHVyZTIwMTkiLCJSc2FTaWduYXR1cmUyMDE4Il19LCJsZHBfdmMiOnsicHJvb2ZfdHlwZSI6WyJKc29uV2ViU2lnbmF0dXJlMjAyMCIsIkVkMjU1MTlTaWduYXR1cmUyMDE4IiwiRWNkc2FTZWNwMjU2azFTaWduYXR1cmUyMDE5IiwiUnNhU2lnbmF0dXJlMjAxOCJdfSwibGRwX3ZwIjp7InByb29mX3R5cGUiOlsiSnNvbldlYlNpZ25hdHVyZTIwMjAiLCJFZDI1NTE5U2lnbmF0dXJlMjAxOCIsIkVjZHNhU2VjcDI1NmsxU2lnbmF0dXJlMjAxOSIsIlJzYVNpZ25hdHVyZTIwMTgiXX19LCJpZCI6IjMyZjU0MTYzLTcxNjYtNDhmMS05M2Q4LWZmMjE3YmRiMDY1MyIsImlucHV0X2Rlc2NyaXB0b3JzIjpbeyJjb25zdHJhaW50cyI6eyJmaWVsZHMiOlt7ImZpbHRlciI6eyJjb250YWlucyI6eyJjb25zdCI6IlVuaXZlcnNpdHlEZWdyZWVDcmVkZW50aWFsIiwidHlwZSI6InN0cmluZyJ9LCJ0eXBlIjoiYXJyYXkifSwicGF0aCI6WyIkLnR5cGUiLCIkLnZjLnR5cGUiXX1dfSwiaWQiOiJkZWdyZWUiLCJuYW1lIjoiRGVncmVlIiwicHVycG9zZSI6IldlIGNhbiBvbmx5IGhpcmUgd2l0aCB1bml2ZXJzaXR5IGRlZ3JlZS4ifV19fX0sImNsaWVudF9pZCI6ImRpZDppb246RWlDZ3hETFJjTmpzZ1lHWVd5UHRvZXJnVTNuUGo4UnFlck1XVzE0TGE3V2FQZzpleUprWld4MFlTSTZleUp3WVhSamFHVnpJanBiZXlKaFkzUnBiMjRpT2lKaFpHUXRjSFZpYkdsakxXdGxlWE1pTENKd2RXSnNhV05MWlhseklqcGJleUpwWkNJNklrZFNYemRCVEhSQ05rWjRUM3B6ZWsxeWEyTmZNVFZCWW1kbFJEaDZiVGxCYVVwWGN6VlpObk5xZERnaUxDSndkV0pzYVdOTFpYbEtkMnNpT25zaVkzSjJJam9pUldReU5UVXhPU0lzSW10cFpDSTZJa2RTWHpkQlRIUkNOa1o0VDNwemVrMXlhMk5mTVRWQlltZGxSRGg2YlRsQmFVcFhjelZaTm5OcWREZ2lMQ0pyZEhraU9pSlBTMUFpTENKNElqb2lSMjFOY1dSaGNWaFpTMmhDTTFwNkxXdzVhRTlDYlhobFowaFNOMUF4UVdsTFZ5MVlaVWROTUd4dFp5SjlMQ0p3ZFhKd2IzTmxjeUk2V3lKaGRYUm9aVzUwYVdOaGRHbHZiaUlzSW1GemMyVnlkR2x2YmsxbGRHaHZaQ0pkTENKMGVYQmxJam9pUldReU5UVXhPVlpsY21sbWFXTmhkR2x2Ymt0bGVUSXdNVGdpZlYxOUxIc2lZV04wYVc5dUlqb2lZV1JrTFhObGNuWnBZMlZ6SWl3aWMyVnlkbWxqWlhNaU9sdDdJbWxrSWpvaVRHbHVhMlZrUkc5dFlXbHVjeUlzSW5ObGNuWnBZMlZGYm1Sd2IybHVkQ0k2ZXlKdmNtbG5hVzV6SWpwYkltaDBkSEE2THk5MlkzTXVkMlZpYUc5dmF5NWxlR0Z0Y0d4bExtTnZiVG80TVRnd0x5SmRmU3dpZEhsd1pTSTZJa3hwYm10bFpFUnZiV0ZwYm5NaWZWMTlYU3dpZFhCa1lYUmxRMjl0YldsMGJXVnVkQ0k2SWtWcFFqbHlZWE42UjBOalVtVnVSVTQzTUVoMlN6bE5kbDlpVEVseVdXWmtVbVZUZGs5VlRubHpabkY1YmxFaWZTd2ljM1ZtWm1sNFJHRjBZU0k2ZXlKa1pXeDBZVWhoYzJnaU9pSkZhVVIxVGpSa2JGOUlTMWhZYlVOTmFHNWphR3MxYW5nelFVcG5abXR6ZW1oS1UxQnlObGRuYkdkamJWUlJJaXdpY21WamIzWmxjbmxEYjIxdGFYUnRaVzUwSWpvaVJXbEJOVFpyUlZaekxURkVZMDlJYzNkcllWSmlTazVZVlc1Tk1tWnVaWGxyWm5SUFRVZGFiWFowTlZrd2R5SjlMQ0owZVhCbElqb2lZM0psWVhSbEluMCIsImNsaWVudF9pZF9zY2hlbWUiOiJkaWQiLCJjbGllbnRfbWV0YWRhdGEiOnsiY2xpZW50X25hbWUiOiJ2X2xkcF91bml2ZXJzaXR5X2RlZ3JlZSIsImNsaWVudF9wdXJwb3NlIjoidGVzdCBwdXJwb3NlLiIsImxvZ29fdXJpIjoiIiwic3ViamVjdF9zeW50YXhfdHlwZXNfc3VwcG9ydGVkIjpbImRpZDp3ZWIiLCJkaWQ6andrIiwiZGlkOmtleSIsImRpZDppb24iXSwidnBfZm9ybWF0cyI6eyJsZHBfdmMiOnsicHJvb2ZfdHlwZSI6WyJFZDI1NTE5U2lnbmF0dXJlMjAxOCIsIkVkMjU1MTlTaWduYXR1cmUyMDIwIiwiSnNvbldlYlNpZ25hdHVyZTIwMjAiLCJFY2RzYVNlY3AyNTZrMVNpZ25hdHVyZTIwMTkiLCJCYnNCbHNTaWduYXR1cmUyMDIwIl19LCJsZHBfdnAiOnsicHJvb2ZfdHlwZSI6WyJFZDI1NTE5U2lnbmF0dXJlMjAxOCIsIkVkMjU1MTlTaWduYXR1cmUyMDIwIiwiSnNvbldlYlNpZ25hdHVyZTIwMjAiLCJFY2RzYVNlY3AyNTZrMVNpZ25hdHVyZTIwMTkiLCJCYnNCbHNTaWduYXR1cmUyMDIwIl19fX0sImV4cCI6MTczMDExMjQ2MywiaWF0IjoxNzMwMTExNTYzLCJpc3MiOiJkaWQ6aW9uOkVpQ2d4RExSY05qc2dZR1lXeVB0b2VyZ1UzblBqOFJxZXJNV1cxNExhN1dhUGc6ZXlKa1pXeDBZU0k2ZXlKd1lYUmphR1Z6SWpwYmV5SmhZM1JwYjI0aU9pSmhaR1F0Y0hWaWJHbGpMV3RsZVhNaUxDSndkV0pzYVdOTFpYbHpJanBiZXlKcFpDSTZJa2RTWHpkQlRIUkNOa1o0VDNwemVrMXlhMk5mTVRWQlltZGxSRGg2YlRsQmFVcFhjelZaTm5OcWREZ2lMQ0p3ZFdKc2FXTkxaWGxLZDJzaU9uc2lZM0oySWpvaVJXUXlOVFV4T1NJc0ltdHBaQ0k2SWtkU1h6ZEJUSFJDTmtaNFQzcHplazF5YTJOZk1UVkJZbWRsUkRoNmJUbEJhVXBYY3pWWk5uTnFkRGdpTENKcmRIa2lPaUpQUzFBaUxDSjRJam9pUjIxTmNXUmhjVmhaUzJoQ00xcDZMV3c1YUU5Q2JYaGxaMGhTTjFBeFFXbExWeTFZWlVkTk1HeHRaeUo5TENKd2RYSndiM05sY3lJNld5SmhkWFJvWlc1MGFXTmhkR2x2YmlJc0ltRnpjMlZ5ZEdsdmJrMWxkR2h2WkNKZExDSjBlWEJsSWpvaVJXUXlOVFV4T1ZabGNtbG1hV05oZEdsdmJrdGxlVEl3TVRnaWZWMTlMSHNpWVdOMGFXOXVJam9pWVdSa0xYTmxjblpwWTJWeklpd2ljMlZ5ZG1salpYTWlPbHQ3SW1sa0lqb2lUR2x1YTJWa1JHOXRZV2x1Y3lJc0luTmxjblpwWTJWRmJtUndiMmx1ZENJNmV5SnZjbWxuYVc1eklqcGJJbWgwZEhBNkx5OTJZM011ZDJWaWFHOXZheTVsZUdGdGNHeGxMbU52YlRvNE1UZ3dMeUpkZlN3aWRIbHdaU0k2SWt4cGJtdGxaRVJ2YldGcGJuTWlmVjE5WFN3aWRYQmtZWFJsUTI5dGJXbDBiV1Z1ZENJNklrVnBRamx5WVhONlIwTmpVbVZ1UlU0M01FaDJTemxOZGw5aVRFbHlXV1prVW1WVGRrOVZUbmx6Wm5GNWJsRWlmU3dpYzNWbVptbDRSR0YwWVNJNmV5SmtaV3gwWVVoaGMyZ2lPaUpGYVVSMVRqUmtiRjlJUzFoWWJVTk5hRzVqYUdzMWFuZ3pRVXBuWm10emVtaEtVMUJ5TmxkbmJHZGpiVlJSSWl3aWNtVmpiM1psY25sRGIyMXRhWFJ0Wlc1MElqb2lSV2xCTlRaclJWWnpMVEZFWTA5SWMzZHJZVkppU2s1WVZXNU5NbVp1WlhsclpuUlBUVWRhYlhaME5Wa3dkeUo5TENKMGVYQmxJam9pWTNKbFlYUmxJbjAiLCJqdGkiOiJmMGY4M2M0ZC00OTM1LTQyZGMtYWM1Mi1mMWUyMTZjZjUyNmQiLCJub25jZSI6Ik9rQVE1VmZnSEMyQzdBPT0iLCJwcmVzZW50YXRpb25fZGVmaW5pdGlvbiI6eyJmb3JtYXQiOnsibGRwIjp7InByb29mX3R5cGUiOlsiSnNvbldlYlNpZ25hdHVyZTIwMjAiLCJFZDI1NTE5U2lnbmF0dXJlMjAxOCIsIkVjZHNhU2VjcDI1NmsxU2lnbmF0dXJlMjAxOSIsIlJzYVNpZ25hdHVyZTIwMTgiXX0sImxkcF92YyI6eyJwcm9vZl90eXBlIjpbIkpzb25XZWJTaWduYXR1cmUyMDIwIiwiRWQyNTUxOVNpZ25hdHVyZTIwMTgiLCJFY2RzYVNlY3AyNTZrMVNpZ25hdHVyZTIwMTkiLCJSc2FTaWduYXR1cmUyMDE4Il19LCJsZHBfdnAiOnsicHJvb2ZfdHlwZSI6WyJKc29uV2ViU2lnbmF0dXJlMjAyMCIsIkVkMjU1MTlTaWduYXR1cmUyMDE4IiwiRWNkc2FTZWNwMjU2azFTaWduYXR1cmUyMDE5IiwiUnNhU2lnbmF0dXJlMjAxOCJdfX0sImlkIjoiMzJmNTQxNjMtNzE2Ni00OGYxLTkzZDgtZmYyMTdiZGIwNjUzIiwiaW5wdXRfZGVzY3JpcHRvcnMiOlt7ImNvbnN0cmFpbnRzIjp7ImZpZWxkcyI6W3siZmlsdGVyIjp7ImNvbnRhaW5zIjp7ImNvbnN0IjoiVW5pdmVyc2l0eURlZ3JlZUNyZWRlbnRpYWwiLCJ0eXBlIjoic3RyaW5nIn0sInR5cGUiOiJhcnJheSJ9LCJwYXRoIjpbIiQudHlwZSIsIiQudmMudHlwZSJdfV19LCJpZCI6ImRlZ3JlZSIsIm5hbWUiOiJEZWdyZWUiLCJwdXJwb3NlIjoiV2UgY2FuIG9ubHkgaGlyZSB3aXRoIHVuaXZlcnNpdHkgZGVncmVlLiJ9XX0sInJlZGlyZWN0X3VyaSI6Imh0dHA6Ly9sb2NhbGhvc3Q6ODA3NS9vaWRjL3ByZXNlbnQiLCJyZWdpc3RyYXRpb24iOnsiY2xpZW50X25hbWUiOiJ2X2xkcF91bml2ZXJzaXR5X2RlZ3JlZSIsImNsaWVudF9wdXJwb3NlIjoidGVzdCBwdXJwb3NlLiIsImxvZ29fdXJpIjoiIiwic3ViamVjdF9zeW50YXhfdHlwZXNfc3VwcG9ydGVkIjpbImRpZDppb24iXSwidnBfZm9ybWF0cyI6eyJsZHBfdmMiOnsicHJvb2ZfdHlwZSI6WyJFZDI1NTE5U2lnbmF0dXJlMjAxOCIsIkVkMjU1MTlTaWduYXR1cmUyMDIwIiwiSnNvbldlYlNpZ25hdHVyZTIwMjAiLCJFY2RzYVNlY3AyNTZrMVNpZ25hdHVyZTIwMTkiLCJCYnNCbHNTaWduYXR1cmUyMDIwIl19LCJsZHBfdnAiOnsicHJvb2ZfdHlwZSI6WyJFZDI1NTE5U2lnbmF0dXJlMjAxOCIsIkVkMjU1MTlTaWduYXR1cmUyMDIwIiwiSnNvbldlYlNpZ25hdHVyZTIwMjAiLCJFY2RzYVNlY3AyNTZrMVNpZ25hdHVyZTIwMTkiLCJCYnNCbHNTaWduYXR1cmUyMDIwIl19fX0sInJlc3BvbnNlX21vZGUiOiJkaXJlY3RfcG9zdCIsInJlc3BvbnNlX3R5cGUiOiJ2cF90b2tlbiBpZF90b2tlbiIsInJlc3BvbnNlX3VyaSI6Imh0dHA6Ly9sb2NhbGhvc3Q6ODA3NS9vaWRjL3ByZXNlbnQiLCJzY29wZSI6Im9wZW5pZCIsInN0YXRlIjoiMDJmMDg4YmEtNDFmNi00MjhkLWIwMzAtMDcwMGU3MTE2ZjAyIn0.gcqRJnFBvC8rHb_bAhLXv3Ez0sQoKjxjPqAm4vhQuJfvYSNAFKj79YxkUC8P5mdHZI7Psnic9nPH1FTel_QJDg \ No newline at end of file diff --git a/test/integration/cli/go.sum b/test/integration/cli/go.sum index be2668e9..5bdf944d 100644 --- a/test/integration/cli/go.sum +++ b/test/integration/cli/go.sum @@ -45,14 +45,13 @@ go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY= go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= golang.org/x/oauth2 v0.13.0 h1:jDDenyj+WgFtmV3zYVoi8aE2BwtXFLWOA67ZfNWftiY= golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/test/integration/go.sum b/test/integration/go.sum index e153db02..015f99a6 100644 --- a/test/integration/go.sum +++ b/test/integration/go.sum @@ -203,16 +203,14 @@ golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= -golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= +golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ= golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= golang.org/x/oauth2 v0.13.0 h1:jDDenyj+WgFtmV3zYVoi8aE2BwtXFLWOA67ZfNWftiY= golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0= @@ -221,13 +219,11 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=