From e5030f3d81ac7cad31f7b9df67af4808997b5391 Mon Sep 17 00:00:00 2001 From: Stas Dmytryshyn Date: Tue, 7 Jan 2025 14:50:18 +0100 Subject: [PATCH] feat: add support for data-integrity migration (#1831) --- pkg/doc/vc/crypto/dataIntegrity.go | 16 ++++++++++++---- pkg/doc/vc/crypto/dataIntegrity_test.go | 21 +++++++++++++++++++++ 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/pkg/doc/vc/crypto/dataIntegrity.go b/pkg/doc/vc/crypto/dataIntegrity.go index 0781465e6..3e87600d3 100644 --- a/pkg/doc/vc/crypto/dataIntegrity.go +++ b/pkg/doc/vc/crypto/dataIntegrity.go @@ -20,7 +20,8 @@ import ( ) const ( - dataIntegrityProofContext = "https://w3id.org/security/data-integrity/v2" + dataIntegrityProofContextV1 = "https://w3id.org/security/data-integrity/v1" + dataIntegrityProofContextV2 = "https://w3id.org/security/data-integrity/v2" ) // signCredentialLDP adds verifiable.DataIntegrityProofContext to the VC. @@ -68,9 +69,16 @@ func (c *Crypto) signCredentialLDPDataIntegrity(signerData *vc.Signer, } // Update VC context for Data Integrity. - if !lo.Contains(vc.Contents().Context, verifiable.V2ContextURI) { // for v2 its already embedded - if !lo.Contains(vc.Contents().Context, dataIntegrityProofContext) { - vc = vc.WithModifiedContext(append(vc.Contents().Context, dataIntegrityProofContext)) + contexts := vc.Contents().Context + if !lo.Contains(contexts, verifiable.V2ContextURI) { // for v2 its already embedded + if lo.Contains(contexts, dataIntegrityProofContextV1) { // backward compatibility. Migrate old creds to v2 + contexts = lo.Filter(contexts, func(s string, _ int) bool { + return s != dataIntegrityProofContextV1 + }) + } + + if !lo.Contains(contexts, dataIntegrityProofContextV2) { + vc = vc.WithModifiedContext(append(contexts, dataIntegrityProofContextV2)) } } diff --git a/pkg/doc/vc/crypto/dataIntegrity_test.go b/pkg/doc/vc/crypto/dataIntegrity_test.go index 54fe1be0b..ee2c1a28f 100644 --- a/pkg/doc/vc/crypto/dataIntegrity_test.go +++ b/pkg/doc/vc/crypto/dataIntegrity_test.go @@ -101,6 +101,27 @@ func TestCrypto_SignCredentialLDPDataIntegrity(t *testing.T) { //nolint:gocognit require.NotEmpty(t, signedVC.Proofs()[0]["proofValue"]) }) + t.Run("Success with v1 migration", func(t *testing.T) { + unsignedVc = unsignedVc.WithModifiedContext( + append(unsignedVc.Contents().Context, dataIntegrityProofContextV1), + ) + + signedVC, err := c.signCredentialLDPDataIntegrity(testSigner, unsignedVc) + require.NoError(t, err) + require.Equal(t, 1, len(signedVC.Proofs())) + + require.Equal(t, "DataIntegrityProof", signedVC.Proofs()[0]["type"]) + require.Equal(t, "ecdsa-2019", signedVC.Proofs()[0]["cryptosuite"]) + require.Equal(t, "#key1", signedVC.Proofs()[0]["verificationMethod"]) + require.Equal(t, "assertionMethod", signedVC.Proofs()[0]["proofPurpose"]) + require.Empty(t, signedVC.Proofs()[0]["challenge"]) + require.Empty(t, signedVC.Proofs()[0]["domain"]) + require.NotEmpty(t, signedVC.Proofs()[0]["proofValue"]) + + require.NotContains(t, signedVC.Contents().Context, dataIntegrityProofContextV1) + require.Contains(t, signedVC.Contents().Context, dataIntegrityProofContextV2) + }) + t.Run("Success ecdsa-rdfc-2019", func(t *testing.T) { legacySigner := getTestLDPDataIntegritySigner( ecdsa2019.SuiteTypeNew,