From 5a6d23d1bd74e5bf3cebed180c2918bd81f8b1f3 Mon Sep 17 00:00:00 2001 From: arnabghose997 Date: Tue, 8 Nov 2022 00:48:22 +0530 Subject: [PATCH 1/2] did-doc controllers can register schema and credential statuses --- .../credential_verification.go | 45 +++++ .../document_verification/did_verification.go | 9 + x/ssi/keeper/msg_server_credential.go | 28 ++- x/ssi/keeper/msg_server_did.go | 8 +- x/ssi/keeper/msg_server_schema.go | 7 +- x/ssi/keeper/signature_verification.go | 173 +++++------------- x/ssi/types/types.go | 1 - 7 files changed, 132 insertions(+), 139 deletions(-) diff --git a/x/ssi/keeper/document_verification/credential_verification.go b/x/ssi/keeper/document_verification/credential_verification.go index b424122..4f8d8f2 100644 --- a/x/ssi/keeper/document_verification/credential_verification.go +++ b/x/ssi/keeper/document_verification/credential_verification.go @@ -2,6 +2,11 @@ package verification import ( "regexp" + "time" + "fmt" + + "github.com/hypersign-protocol/hid-node/x/ssi/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) func VerifyCredentialHash(credHash string) bool { @@ -19,3 +24,43 @@ func VerifyCredentialHash(credHash string) bool { return matchFound } + +func VerifyCredentialStatusDates(issuanceDate time.Time, expirationDate time.Time) error { + var dateDiff int64 = int64(expirationDate.Sub(issuanceDate)) / 1e9 // converting nanoseconds to seconds + if dateDiff < 0 { + return sdkerrors.Wrapf(types.ErrInvalidDate, fmt.Sprintf("expiration date %s cannot be less than issuance date %s", expirationDate, issuanceDate)) + } + + return nil +} + +func VerifyCredentialProofDates(credProof *types.CredentialProof, credRegistration bool) error { + var dateDiff int64 + + proofCreatedDate := credProof.GetCreated() + proofCreatedDateParsed, err := time.Parse(time.RFC3339, proofCreatedDate) + if err != nil { + return sdkerrors.Wrapf(types.ErrInvalidDate, fmt.Sprintf("invalid created date format: %s", proofCreatedDate)) + } + + proofUpdatedDate := credProof.GetUpdated() + proofUpdatedDateParsed, err := time.Parse(time.RFC3339, proofUpdatedDate) + if err != nil { + return sdkerrors.Wrapf(types.ErrInvalidDate, fmt.Sprintf("invalid created date format: %s", proofUpdatedDate)) + } + + // If credRegistration is True, check for equity of updated and created dates will proceeed + // Else, check for updated date being greater than created date will proceeed + if credRegistration { + if !proofUpdatedDateParsed.Equal(proofCreatedDateParsed) { + return sdkerrors.Wrapf(types.ErrInvalidDate, fmt.Sprintf("updated date %s should be similar to created date %s", proofUpdatedDate, proofCreatedDate)) + } + } else { + dateDiff = int64(proofUpdatedDateParsed.Sub(proofCreatedDateParsed)) / 1e9 // converting nanoseconds to seconds + if dateDiff <= 0 { + return sdkerrors.Wrapf(types.ErrInvalidDate, fmt.Sprintf("update date %s cannot be less than or equal to created date %s in case of credential status update", proofUpdatedDate, proofCreatedDate)) + } + } + + return nil +} diff --git a/x/ssi/keeper/document_verification/did_verification.go b/x/ssi/keeper/document_verification/did_verification.go index 3ce845b..e8c8630 100644 --- a/x/ssi/keeper/document_verification/did_verification.go +++ b/x/ssi/keeper/document_verification/did_verification.go @@ -103,3 +103,12 @@ func ValidateDidDocument(didDoc *types.Did, genesisNamespace string) error { return nil } + + +// Check the Deactivate status of DID +func VerifyDidDeactivate(metadata *types.Metadata, id string) error { + if metadata.GetDeactivated() { + return sdkerrors.Wrap(types.ErrDidDocDeactivated, fmt.Sprintf("DidDoc ID: %s", id)) + } + return nil +} diff --git a/x/ssi/keeper/msg_server_credential.go b/x/ssi/keeper/msg_server_credential.go index 4c68f5a..4ffd22d 100644 --- a/x/ssi/keeper/msg_server_credential.go +++ b/x/ssi/keeper/msg_server_credential.go @@ -62,12 +62,12 @@ func (k msgServer) RegisterCredentialStatus(goCtx context.Context, msg *types.Ms return nil, sdkerrors.Wrapf(types.ErrInvalidDate, fmt.Sprintf("invalid issuance date format: %s", issuanceDate)) } - if err := VerifyCredentialStatusDates(issuanceDateParsed, expirationDateParsed); err != nil { + if err := verify.VerifyCredentialStatusDates(issuanceDateParsed, expirationDateParsed); err != nil { return nil, err } // Check if updated date iss imilar to created date - if err := VerifyCredentialProofDates(credProof, true); err != nil { + if err := verify.VerifyCredentialProofDates(credProof, true); err != nil { return nil, err } @@ -90,10 +90,14 @@ func (k msgServer) RegisterCredentialStatus(goCtx context.Context, msg *types.Ms } did := didDocument.GetDidDocument() - signature := credProof.GetProofValue() - verificationMethod := credProof.GetVerificationMethod() - err = k.VerifyCredentialSignature(credMsg, did, signature, verificationMethod) + // Verify Signature + signature := &types.SignInfo{ + VerificationMethodId: credProof.GetVerificationMethod(), + Signature: credProof.GetProofValue(), + } + signatures := []*types.SignInfo{signature} + err = k.VerifyDocumentSignature(&ctx, credMsg, did, signatures) if err != nil { return nil, err } @@ -190,12 +194,12 @@ func (k msgServer) updateCredentialStatus(ctx sdk.Context, newCredStatus *types. } // Check if new expiration date isn't less than new issuance date - if err := VerifyCredentialStatusDates(newIssuanceDateParsed, newExpirationDateParsed); err != nil { + if err := verify.VerifyCredentialStatusDates(newIssuanceDateParsed, newExpirationDateParsed); err != nil { return nil, err } // Check if updated date iss imilar to created date - if err := VerifyCredentialProofDates(newCredProof, false); err != nil { + if err := verify.VerifyCredentialProofDates(newCredProof, false); err != nil { return nil, err } @@ -257,10 +261,14 @@ func (k msgServer) updateCredentialStatus(ctx sdk.Context, newCredStatus *types. } did := didDocument.GetDidDocument() - signature := newCredProof.GetProofValue() - verificationMethod := newCredProof.GetVerificationMethod() - err = k.VerifyCredentialSignature(newCredStatus, did, signature, verificationMethod) + // Verify Signature + signature := &types.SignInfo{ + VerificationMethodId: newCredProof.GetVerificationMethod(), + Signature: newCredProof.GetProofValue(), + } + signatures := []*types.SignInfo{signature} + err = k.VerifyDocumentSignature(&ctx, newCredStatus, did, signatures) if err != nil { return nil, err } diff --git a/x/ssi/keeper/msg_server_did.go b/x/ssi/keeper/msg_server_did.go index 1518d53..ba432d1 100644 --- a/x/ssi/keeper/msg_server_did.go +++ b/x/ssi/keeper/msg_server_did.go @@ -40,7 +40,7 @@ func (k msgServer) CreateDID(goCtx context.Context, msg *types.MsgCreateDID) (*t } // Verification of Did Document Signature - if err := k.VerifySignature(&ctx, didMsg, didSigners, signatures); err != nil { + if err := k.VerifyDidSignature(&ctx, didMsg, didSigners, signatures); err != nil { return nil, err } @@ -88,7 +88,7 @@ func (k msgServer) UpdateDID(goCtx context.Context, msg *types.MsgUpdateDID) (*t oldMetaData := oldDIDDoc.GetDidDocumentMetadata() // Check if the status of DID Document is deactivated - if err := VerifyDidDeactivate(oldMetaData, didId); err != nil { + if err := verify.VerifyDidDeactivate(oldMetaData, didId); err != nil { return nil, err } @@ -157,7 +157,7 @@ func (k msgServer) DeactivateDID(goCtx context.Context, msg *types.MsgDeactivate oldVersionId := metadata.GetVersionId() // Check if the DID is already deactivated - if err := VerifyDidDeactivate(metadata, didId); err != nil { + if err := verify.VerifyDidDeactivate(metadata, didId); err != nil { return nil, err } @@ -177,7 +177,7 @@ func (k msgServer) DeactivateDID(goCtx context.Context, msg *types.MsgDeactivate // Signature Verification signers := didDoc.GetSigners() signatures := msg.Signatures - if err := k.VerifySignature(&ctx, didDoc, signers, signatures); err != nil { + if err := k.VerifyDidSignature(&ctx, didDoc, signers, signatures); err != nil { return nil, err } diff --git a/x/ssi/keeper/msg_server_schema.go b/x/ssi/keeper/msg_server_schema.go index 878d44e..a13b61d 100644 --- a/x/ssi/keeper/msg_server_schema.go +++ b/x/ssi/keeper/msg_server_schema.go @@ -64,7 +64,12 @@ func (k msgServer) CreateSchema(goCtx context.Context, msg *types.MsgCreateSchem } // Signature check - if err := k.VerifySchemaSignature(schemaDoc, authorDidDocument.DidDocument, schemaProof.ProofValue, schemaProof.VerificationMethod); err != nil { + signature := &types.SignInfo{ + VerificationMethodId: schemaProof.VerificationMethod, + Signature: schemaProof.ProofValue, + } + signatures := []*types.SignInfo{signature} + if err := k.VerifyDocumentSignature(&ctx, schemaDoc, authorDidDocument.DidDocument, signatures); err != nil { return nil, err } diff --git a/x/ssi/keeper/signature_verification.go b/x/ssi/keeper/signature_verification.go index d8a546d..69f4977 100644 --- a/x/ssi/keeper/signature_verification.go +++ b/x/ssi/keeper/signature_verification.go @@ -5,7 +5,6 @@ import ( "encoding/base64" "fmt" "reflect" - "time" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" @@ -14,6 +13,8 @@ import ( "github.com/hypersign-protocol/hid-node/x/ssi/utils" ) +// Verify signatures against signer's public keys +// If atleast one of the signatures is valid, return true func VerifyIdentitySignature(signer types.Signer, signatures []*types.SignInfo, signingInput []byte) (bool, error) { result := false @@ -54,48 +55,29 @@ func (k msgServer) VerifySignatureOnDidUpdate(ctx *sdk.Context, oldDIDDoc *types // Verification Method has been deleted if newVM == nil { - signers = AppendSignerIfNeed(signers, oldVM.Controller, newDIDDoc) + signers = appendSignerIfNeed(signers, oldVM.Controller, newDIDDoc) continue } // Verification Method has been changed if !reflect.DeepEqual(oldVM, newVM) { - signers = AppendSignerIfNeed(signers, newVM.Controller, newDIDDoc) + signers = appendSignerIfNeed(signers, newVM.Controller, newDIDDoc) } // Verification Method Controller has been changed, need to add old controller if newVM.Controller != oldVM.Controller { - signers = AppendSignerIfNeed(signers, oldVM.Controller, newDIDDoc) + signers = appendSignerIfNeed(signers, oldVM.Controller, newDIDDoc) } } - if err := k.VerifySignature(ctx, newDIDDoc, signers, signatures); err != nil { + if err := k.VerifyDidSignature(ctx, newDIDDoc, signers, signatures); err != nil { return err } return nil } -func AppendSignerIfNeed(signers []types.Signer, controller string, msg *types.Did) []types.Signer { - for _, signer := range signers { - if signer.Signer == controller { - return signers - } - } - - signer := types.Signer{ - Signer: controller, - } - - if controller == msg.Id { - signer.VerificationMethod = msg.VerificationMethod - signer.Authentication = msg.Authentication - } - - return append(signers, signer) -} - -func (k *Keeper) VerifySignature(ctx *sdk.Context, msg *types.Did, signers []types.Signer, signatures []*types.SignInfo) error { +func (k *Keeper) VerifyDidSignature(ctx *sdk.Context, msg *types.Did, signers []types.Signer, signatures []*types.SignInfo) error { var validArr []types.ValidDid if len(signers) == 0 { @@ -135,140 +117,85 @@ func (k *Keeper) VerifySignature(ctx *sdk.Context, msg *types.Did, signers []typ return nil } -func (k *Keeper) VerifySchemaSignature(msg *types.SchemaDocument, didDoc *types.Did, signature string, verificationMethod string) error { +// Verify Signature for Credential Schema and Credential Status Documents +func (k *Keeper) VerifyDocumentSignature(ctx *sdk.Context, msg types.IdentityMsg, didDoc *types.Did, signatures []*types.SignInfo) error { + var validArr []types.ValidDid signingInput := msg.GetSignBytes() + signers := didDoc.GetSigners() - signer := types.Signer{ - Signer: didDoc.GetId(), - AssertionMethod: didDoc.GetAssertionMethod(), - VerificationMethod: didDoc.GetVerificationMethod(), - } + for _, signer := range signers { + if signer.VerificationMethod == nil { + fetchedDidDoc, err := k.GetDid(ctx, signer.Signer) + if err != nil { + return types.ErrDidDocNotFound.Wrap(signer.Signer) + } - signingInfo := &types.SignInfo{ - VerificationMethodId: verificationMethod, - Signature: signature, - } + signer.Authentication = fetchedDidDoc.DidDocument.Authentication + signer.VerificationMethod = fetchedDidDoc.DidDocument.VerificationMethod + } - signingInfoList := []*types.SignInfo{ - signingInfo, + valid, err := VerifyIdentitySignature(signer, signatures, signingInput) + if err != nil { + return sdkerrors.Wrap(types.ErrInvalidSignature, err.Error()) + } + validArr = append(validArr, types.ValidDid{DidId: signer.Signer, IsValid: valid}) } + + validDid := verify.HasAtleastOneTrueSigner(validArr) - valid, err := VerifyIdentitySignature(signer, signingInfoList, signingInput) - if err != nil { - return sdkerrors.Wrap(types.ErrInvalidSignature, err.Error()) + if validDid == (types.ValidDid{}) { + return sdkerrors.Wrap(types.ErrInvalidSignature, validDid.DidId) } - if !valid { - return sdkerrors.Wrap(types.ErrInvalidSignature, signer.Signer) - } - return nil -} - -func (k *Keeper) ValidateController(ctx *sdk.Context, id string, controller string) error { - if id == controller { - return nil - } - didDoc, err := k.GetDid(ctx, controller) - if err != nil { - return types.ErrDidDocNotFound.Wrap(controller) - } - if len(didDoc.DidDocument.Authentication) == 0 { - return types.ErrBadRequestInvalidVerMethod.Wrap( - fmt.Sprintf("Verificatition method controller %s doesn't have an authentication keys", controller)) - } return nil } func (k msgServer) ValidateDidControllers(ctx *sdk.Context, id string, controllers []string, verMethods []*types.VerificationMethod) error { for _, verificationMethod := range verMethods { - if err := k.ValidateController(ctx, id, verificationMethod.Controller); err != nil { + if err := k.validateController(ctx, id, verificationMethod.Controller); err != nil { return err } } for _, didController := range controllers { - if err := k.ValidateController(ctx, id, didController); err != nil { + if err := k.validateController(ctx, id, didController); err != nil { return err } } return nil } -// Check the Deactivate status of DID -func VerifyDidDeactivate(metadata *types.Metadata, id string) error { - if metadata.GetDeactivated() { - return sdkerrors.Wrap(types.ErrDidDocDeactivated, fmt.Sprintf("DidDoc ID: %s", id)) - } - return nil -} - -// Verify Credential Signature -func (k msgServer) VerifyCredentialSignature(msg *types.CredentialStatus, didDoc *types.Did, signature string, verificationMethod string) error { - signingInput := msg.GetSignBytes() - - signer := types.Signer{ - Signer: didDoc.GetId(), - AssertionMethod: didDoc.GetAssertionMethod(), - VerificationMethod: didDoc.GetVerificationMethod(), - } - - signingInfo := &types.SignInfo{ - VerificationMethodId: verificationMethod, - Signature: signature, - } - - signingInfoList := []*types.SignInfo{ - signingInfo, +func (k *Keeper) validateController(ctx *sdk.Context, id string, controller string) error { + if id == controller { + return nil } - - valid, err := VerifyIdentitySignature(signer, signingInfoList, signingInput) + didDoc, err := k.GetDid(ctx, controller) if err != nil { - return sdkerrors.Wrap(types.ErrInvalidSignature, err.Error()) - } - - if !valid { - return sdkerrors.Wrap(types.ErrInvalidSignature, signer.Signer) + return types.ErrDidDocNotFound.Wrap(controller) } - return nil -} - -func VerifyCredentialStatusDates(issuanceDate time.Time, expirationDate time.Time) error { - var dateDiff int64 = int64(expirationDate.Sub(issuanceDate)) / 1e9 // converting nanoseconds to seconds - if dateDiff < 0 { - return sdkerrors.Wrapf(types.ErrInvalidDate, fmt.Sprintf("expiration date %s cannot be less than issuance date %s", expirationDate, issuanceDate)) + if len(didDoc.DidDocument.Authentication) == 0 { + return types.ErrBadRequestInvalidVerMethod.Wrap( + fmt.Sprintf("Verificatition method controller %s doesn't have an authentication keys", controller)) } - return nil } -func VerifyCredentialProofDates(credProof *types.CredentialProof, credRegistration bool) error { - var dateDiff int64 - - proofCreatedDate := credProof.GetCreated() - proofCreatedDateParsed, err := time.Parse(time.RFC3339, proofCreatedDate) - if err != nil { - return sdkerrors.Wrapf(types.ErrInvalidDate, fmt.Sprintf("invalid created date format: %s", proofCreatedDate)) +func appendSignerIfNeed(signers []types.Signer, controller string, msg *types.Did) []types.Signer { + for _, signer := range signers { + if signer.Signer == controller { + return signers + } } - proofUpdatedDate := credProof.GetUpdated() - proofUpdatedDateParsed, err := time.Parse(time.RFC3339, proofUpdatedDate) - if err != nil { - return sdkerrors.Wrapf(types.ErrInvalidDate, fmt.Sprintf("invalid created date format: %s", proofUpdatedDate)) + signer := types.Signer{ + Signer: controller, } - // If credRegistration is True, check for equity of updated and created dates will proceeed - // Else, check for updated date being greater than created date will proceeed - if credRegistration { - if !proofUpdatedDateParsed.Equal(proofCreatedDateParsed) { - return sdkerrors.Wrapf(types.ErrInvalidDate, fmt.Sprintf("updated date %s should be similar to created date %s", proofUpdatedDate, proofCreatedDate)) - } - } else { - dateDiff = int64(proofUpdatedDateParsed.Sub(proofCreatedDateParsed)) / 1e9 // converting nanoseconds to seconds - if dateDiff <= 0 { - return sdkerrors.Wrapf(types.ErrInvalidDate, fmt.Sprintf("update date %s cannot be less than or equal to created date %s in case of credential status update", proofUpdatedDate, proofCreatedDate)) - } + if controller == msg.Id { + signer.VerificationMethod = msg.VerificationMethod + signer.Authentication = msg.Authentication } - return nil + return append(signers, signer) } diff --git a/x/ssi/types/types.go b/x/ssi/types/types.go index 2281298..15ae093 100644 --- a/x/ssi/types/types.go +++ b/x/ssi/types/types.go @@ -2,7 +2,6 @@ package types type ( IdentityMsg interface { - GetSigners() []Signer GetSignBytes() []byte } From 641f65ed09fe17936021d018f15ef90985c984ef Mon Sep 17 00:00:00 2001 From: arnabghose997 Date: Thu, 10 Nov 2022 23:05:45 +0530 Subject: [PATCH 2/2] added v0.1.3 upgrade handler --- app/app.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/app.go b/app/app.go index c5eb25f..8ca9458 100644 --- a/app/app.go +++ b/app/app.go @@ -311,6 +311,11 @@ func New( return fromVM, nil }) + app.UpgradeKeeper.SetUpgradeHandler("v013", func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { + ctx.Logger().Info("v0.1.3 upgrade") + return fromVM, nil + }) + // register the staking hooks // NOTE: stakingKeeper above is passed by reference, so that it will contain these hooks app.StakingKeeper = *stakingKeeper.SetHooks(