From 5d9efa64c1a01d15ecd5533dcfd6dea44e50e3ef Mon Sep 17 00:00:00 2001 From: "aziz.karabashov" Date: Tue, 27 Feb 2024 09:11:14 +0500 Subject: [PATCH 01/14] Allow add/remove/revoke cert operations for Vendor accounts with matching Subject/SKID --- types/pki/errors.go | 23 +- x/pki/handler_add_noc_root_cert_test.go | 2 +- x/pki/handler_add_non_root_cert_test.go | 477 ++++++++++++ x/pki/handler_revoke_non_root_cert_test.go | 421 +++++++++++ x/pki/handler_test.go | 694 ------------------ x/pki/keeper/keeper.go | 30 + .../msg_server_add_noc_x_509_root_cert.go | 2 +- x/pki/keeper/msg_server_add_x_509_cert.go | 10 +- .../msg_server_propose_add_x_509_root_cert.go | 2 +- x/pki/keeper/msg_server_remove_x_509_cert.go | 7 +- x/pki/keeper/msg_server_revoke_x_509_cert.go | 31 +- 11 files changed, 957 insertions(+), 742 deletions(-) create mode 100644 x/pki/handler_add_non_root_cert_test.go create mode 100644 x/pki/handler_revoke_non_root_cert_test.go diff --git a/types/pki/errors.go b/types/pki/errors.go index f0ae5052b..bb56db8b1 100644 --- a/types/pki/errors.go +++ b/types/pki/errors.go @@ -47,7 +47,6 @@ var ( ErrCertificateVidNotEqualMsgVid = sdkerrors.Register(ModuleName, 436, "certificate's vid is not equal to the message vid") ErrMessageVidNotEqualRootCertVid = sdkerrors.Register(ModuleName, 437, "Message vid is not equal to ledger's root certificate vid") ErrCertNotChainedBack = sdkerrors.Register(ModuleName, 438, "Certificate is not chained back to a root certificate on DCL") - ErrCertVidNotEqualAccountVid = sdkerrors.Register(ModuleName, 439, "account's vid is not equal to ledger's certificate vid") ) func NewErrUnauthorizedRole(transactionName string, requiredRole types.AccountRole) error { @@ -182,11 +181,18 @@ func NewErrUnauthorizedCertIssuer(subject string, subjectKeyID string) error { func NewErrUnauthorizedCertOwner(subject string, subjectKeyID string) error { return sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, - "Only owner of existing certificates with subject=%v and subjectKeyID=%v "+ - "can add new certificate with the same subject and subjectKeyID", + "Only the owner of certificates with subject=%v and subjectKeyID=%v has the authority "+ + "to add, remove, or revoke a certificate with the same subject and subjectKeyID", subject, subjectKeyID) } +func NewErrUnauthorizedCertVendor(subject string, subjectKeyID string, ownerVid int32) error { + return sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, + "Only the vendor accounts with vid=%d, has the authority "+ + "to add, remove, or revoke a certificate with subject=%v and subjectKeyID=%v", + ownerVid, subject, subjectKeyID) +} + func NewErrProvidedNocCertButExistingNotNoc(subject string, subjectKeyID string) error { return sdkerrors.Wrapf(ErrInappropriateCertificateType, "The existing certificate with the same combination of subject (%v) and subjectKeyID (%v) is not a NOC certificate", @@ -199,13 +205,6 @@ func NewErrProvidedNotNocCertButExistingNoc(subject string, subjectKeyID string) subject, subjectKeyID) } -func NewErrExistingCertVidNotEqualAccountVid(subject string, subjectKeyID string, vid int32) error { - return sdkerrors.Wrapf(ErrCertVidNotEqualAccountVid, - "Certificate with the same combination of subject=%v and subjectKeyID=%v "+ - "has already been published by another vendor with VID=%d.", - subject, subjectKeyID, vid) -} - func NewErrCRLSignerCertificatePidNotEqualMsgPid(certificatePid int32, messagePid int32) error { return sdkerrors.Wrapf( ErrCRLSignerCertificatePidNotEqualMsgPid, @@ -332,10 +331,6 @@ func NewErrMessageRemoveRoot(subject string, subjectKeyID string) error { ) } -func NewErrMessageOnlyOwnerCanExecute(command string) error { - return sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "Only owner can revoke certificate using %s", command) -} - func NewErrUnsupportedOperation(e interface{}) error { return sdkerrors.Wrapf(ErrUnsupportedOperation, "%v", e) } diff --git a/x/pki/handler_add_noc_root_cert_test.go b/x/pki/handler_add_noc_root_cert_test.go index 6c3b60431..75eebc910 100644 --- a/x/pki/handler_add_noc_root_cert_test.go +++ b/x/pki/handler_add_noc_root_cert_test.go @@ -133,7 +133,7 @@ func TestHandler_AddNocX509RootCert_CertificateExist(t *testing.T) { Vid: testconstants.VendorID1, }, nocRoorCert: testconstants.RootCertPem, - err: pkitypes.ErrCertVidNotEqualAccountVid, + err: sdkerrors.ErrUnauthorized, }, } diff --git a/x/pki/handler_add_non_root_cert_test.go b/x/pki/handler_add_non_root_cert_test.go new file mode 100644 index 000000000..fb632d1f2 --- /dev/null +++ b/x/pki/handler_add_non_root_cert_test.go @@ -0,0 +1,477 @@ +package pki + +import ( + "testing" + + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/stretchr/testify/require" + testconstants "github.com/zigbee-alliance/distributed-compliance-ledger/integration_tests/constants" + pkitypes "github.com/zigbee-alliance/distributed-compliance-ledger/types/pki" + dclauthtypes "github.com/zigbee-alliance/distributed-compliance-ledger/x/dclauth/types" + "github.com/zigbee-alliance/distributed-compliance-ledger/x/pki/types" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +func TestHandler_AddX509Cert(t *testing.T) { + setup := Setup(t) + + // store root certificate + rootCertificate := rootCertificate(setup.Trustee1) + setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCertificate) + + for i, role := range []dclauthtypes.AccountRole{ + dclauthtypes.Vendor, + dclauthtypes.CertificationCenter, + dclauthtypes.Trustee, + dclauthtypes.NodeAdmin, + } { + accAddress := GenerateAccAddress() + setup.AddAccount(accAddress, []dclauthtypes.AccountRole{role}, 1) + + // add x509 certificate + addX509Cert := types.NewMsgAddX509Cert(accAddress.String(), testconstants.IntermediateCertPem) + _, err := setup.Handler(setup.Ctx, addX509Cert) + require.NoError(t, err) + + // query certificate + certificate, _ := querySingleApprovedCertificate( + setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) + require.Equal(t, intermediateCertificate(accAddress), *certificate) + + certificateBySubjectKeyID, _ := queryAllApprovedCertificatesBySubjectKeyID(setup, testconstants.IntermediateSubjectKeyID) + require.Equal(t, 1, len(certificateBySubjectKeyID)) + require.Equal(t, i+1, len(certificateBySubjectKeyID[0].Certs)) + + certs := make([]*types.Certificate, 0) + certs = append(certs, certificate, certificateBySubjectKeyID[0].Certs[i]) + for _, cert := range certs { + // check + require.Equal(t, addX509Cert.Cert, cert.PemCert) + require.Equal(t, addX509Cert.Signer, cert.Owner) + require.Equal(t, testconstants.IntermediateSubject, cert.Subject) + require.Equal(t, testconstants.IntermediateSubjectKeyID, cert.SubjectKeyId) + require.Equal(t, testconstants.IntermediateSerialNumber, cert.SerialNumber) + require.False(t, cert.IsRoot) + require.Equal(t, testconstants.IntermediateIssuer, cert.Issuer) + require.Equal(t, testconstants.IntermediateAuthorityKeyID, cert.AuthorityKeyId) + require.Equal(t, testconstants.RootSubject, cert.RootSubject) + require.Equal(t, testconstants.RootSubjectKeyID, cert.RootSubjectKeyId) + } + + // check that unique certificate key is registered + require.True(t, setup.Keeper.IsUniqueCertificatePresent( + setup.Ctx, testconstants.IntermediateIssuer, testconstants.IntermediateSerialNumber)) + + // check that child certificates of issuer contains certificate identifier + issuerChildren, _ := queryChildCertificates( + setup, testconstants.IntermediateIssuer, testconstants.IntermediateAuthorityKeyID) + require.Equal(t, 1, len(issuerChildren.CertIds)) + require.Equal(t, + &types.CertificateIdentifier{ + Subject: testconstants.IntermediateSubject, + SubjectKeyId: testconstants.IntermediateSubjectKeyID, + }, + issuerChildren.CertIds[0]) + + // check that no proposed certificate has been created + _, err = queryProposedCertificate(setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) + require.Error(t, err) + require.Equal(t, codes.NotFound, status.Code(err)) + + // cleanup for next iteration + setup.Keeper.RemoveApprovedCertificates(setup.Ctx, + testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) + setup.Keeper.RemoveUniqueCertificate(setup.Ctx, + testconstants.IntermediateIssuer, testconstants.IntermediateSerialNumber) + setup.Keeper.RemoveChildCertificates(setup.Ctx, + testconstants.IntermediateIssuer, testconstants.IntermediateAuthorityKeyID) + } +} + +func TestHandler_AddX509Cert_ForInvalidCertificate(t *testing.T) { + setup := Setup(t) + + // add x509 certificate + addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.StubCertPem) + _, err := setup.Handler(setup.Ctx, addX509Cert) + require.Error(t, err) + require.True(t, pkitypes.ErrInvalidCertificate.Is(err)) +} + +func TestHandler_AddX509Cert_ForRootCertificate(t *testing.T) { + setup := Setup(t) + + // add root certificate as leaf x509 certificate + addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.RootCertPem) + _, err := setup.Handler(setup.Ctx, addX509Cert) + require.Error(t, err) + require.True(t, pkitypes.ErrInappropriateCertificateType.Is(err)) +} + +func TestHandler_AddX509Cert_ForDuplicate(t *testing.T) { + setup := Setup(t) + + // store root certificate + rootCertificate := rootCertificate(setup.Trustee1) + setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCertificate) + + // store intermediate certificate + addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) + _, err := setup.Handler(setup.Ctx, addX509Cert) + require.NoError(t, err) + + // store intermediate certificate second time + _, err = setup.Handler(setup.Ctx, addX509Cert) + require.Error(t, err) + require.True(t, pkitypes.ErrCertificateAlreadyExists.Is(err)) +} + +func TestHandler_AddX509Cert_ForNocCertificate(t *testing.T) { + setup := Setup(t) + + // store root certificate + rootCertificate := rootCertificate(setup.Trustee1) + setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCertificate) + + // Store the NOC certificate + vendorAccAddress := GenerateAccAddress() + setup.AddAccount(vendorAccAddress, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.Vid) + + nocCertificate := intermediateCertificate(vendorAccAddress) + nocCertificate.SerialNumber = testconstants.TestSerialNumber + nocCertificate.IsNoc = true + + setup.Keeper.AddApprovedCertificate(setup.Ctx, nocCertificate) + // TODO: add the certificate to the ICA store after the store is implemented + uniqueCertificate := types.UniqueCertificate{ + Issuer: nocCertificate.Issuer, + SerialNumber: nocCertificate.SerialNumber, + Present: true, + } + setup.Keeper.SetUniqueCertificate(setup.Ctx, uniqueCertificate) + + // store intermediate certificate + addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) + _, err := setup.Handler(setup.Ctx, addX509Cert) + require.True(t, pkitypes.ErrInappropriateCertificateType.Is(err)) +} + +func TestHandler_AddX509Cert_ForDifferentSerialNumber(t *testing.T) { + setup := Setup(t) + + // store root certificate + rootCertificate := rootCertificate(setup.Trustee1) + setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCertificate) + + // store intermediate certificate with different serial number + intermediateCertificate := intermediateCertificate(setup.Trustee1) + intermediateCertificate.SerialNumber = SerialNumber + setup.Keeper.SetUniqueCertificate( + setup.Ctx, + uniqueCertificate(intermediateCertificate.Issuer, intermediateCertificate.SerialNumber), + ) + setup.Keeper.AddApprovedCertificate(setup.Ctx, intermediateCertificate) + + // store intermediate certificate second time + addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) + _, err := setup.Handler(setup.Ctx, addX509Cert) + require.NoError(t, err) + + // query certificate + certificates, _ := queryApprovedCertificates(setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) + + // check + require.Equal(t, 2, len(certificates.Certs)) + require.NotEqual(t, certificates.Certs[0].SerialNumber, certificates.Certs[1].SerialNumber) + + for _, certificate := range certificates.Certs { + require.Equal(t, addX509Cert.Cert, certificate.PemCert) + require.Equal(t, addX509Cert.Signer, certificate.Owner) + require.Equal(t, testconstants.IntermediateSubject, certificate.Subject) + require.Equal(t, testconstants.IntermediateSubjectKeyID, certificate.SubjectKeyId) + require.False(t, certificate.IsRoot) + require.Equal(t, testconstants.RootSubject, certificate.RootSubject) + require.Equal(t, testconstants.RootSubjectKeyID, certificate.RootSubjectKeyId) + require.Equal(t, testconstants.IntermediateIssuer, certificate.Issuer) + require.Equal(t, testconstants.IntermediateAuthorityKeyID, certificate.AuthorityKeyId) + } +} + +func TestHandler_AddX509Cert_ForDifferentSerialNumberDifferentSigner(t *testing.T) { + setup := Setup(t) + + // store root certificate + rootCertificate := rootCertificate(testconstants.Address1) + setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCertificate) + + // store intermediate certificate with different serial number + intermediateCertificate := intermediateCertificate(testconstants.Address1) + intermediateCertificate.SerialNumber = SerialNumber + setup.Keeper.SetUniqueCertificate( + setup.Ctx, + uniqueCertificate(intermediateCertificate.Issuer, intermediateCertificate.SerialNumber), + ) + setup.Keeper.AddApprovedCertificate(setup.Ctx, intermediateCertificate) + + // store intermediate certificate second time + addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) + _, err := setup.Handler(setup.Ctx, addX509Cert) + require.Error(t, err) + require.True(t, sdkerrors.ErrUnauthorized.Is(err)) +} + +func TestHandler_AddX509Cert_ForAbsentDirectParentCert(t *testing.T) { + setup := Setup(t) + + // add intermediate x509 certificate + addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) + _, err := setup.Handler(setup.Ctx, addX509Cert) + require.Error(t, err) + require.True(t, pkitypes.ErrInvalidCertificate.Is(err)) +} + +func TestHandler_AddX509Cert_ForNoRootCert(t *testing.T) { + setup := Setup(t) + + // add intermediate certificate + intermediateCertificate := intermediateCertificate(setup.Trustee1) + setup.Keeper.AddApprovedCertificate(setup.Ctx, intermediateCertificate) + + // add leaf x509 certificate + addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.LeafCertPem) + _, err := setup.Handler(setup.Ctx, addX509Cert) + require.Error(t, err) + require.True(t, pkitypes.ErrInvalidCertificate.Is(err)) +} + +func TestHandler_AddX509Cert_ForFailedCertificateVerification(t *testing.T) { + setup := Setup(t) + + // add invalid root + invalidRootCertificate := types.NewRootCertificate(testconstants.StubCertPem, + testconstants.RootSubject, testconstants.RootSubjectAsText, testconstants.RootSubjectKeyID, + testconstants.RootSerialNumber, setup.Trustee1.String(), []*types.Grant{}, []*types.Grant{}, testconstants.Vid) + setup.Keeper.AddApprovedCertificate(setup.Ctx, invalidRootCertificate) + + // add intermediate x509 certificate + addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) + _, err := setup.Handler(setup.Ctx, addX509Cert) + require.Error(t, err) + require.True(t, pkitypes.ErrInvalidCertificate.Is(err)) +} + +func TestHandler_AddX509Cert_ForTree(t *testing.T) { + setup := Setup(t) + + // add root x509 certificate + rootCertOptions := createTestRootCertOptions() + proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOptions) + + // add intermediate x509 certificate + addIntermediateX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) + _, err := setup.Handler(setup.Ctx, addIntermediateX509Cert) + require.NoError(t, err) + + // add leaf x509 certificate + addLeafX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.LeafCertPem) + _, err = setup.Handler(setup.Ctx, addLeafX509Cert) + require.NoError(t, err) + + // query root certificate + rootCertificate, _ := querySingleApprovedCertificate(setup, testconstants.RootSubject, testconstants.RootSubjectKeyID) + require.Equal(t, testconstants.RootCertPem, rootCertificate.PemCert) + + // check child certificate identifiers of root certificate + rootCertChildren, _ := queryChildCertificates(setup, testconstants.RootSubject, testconstants.RootSubjectKeyID) + + require.Equal(t, 1, len(rootCertChildren.CertIds)) + require.Equal(t, + certificateIdentifier(testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID), + *rootCertChildren.CertIds[0]) + + // query intermediate certificate + intermediateCertificate, _ := querySingleApprovedCertificate(setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) + require.Equal(t, testconstants.IntermediateCertPem, intermediateCertificate.PemCert) + + // check child certificate identifiers of intermediate certificate + intermediateCertChildren, _ := queryChildCertificates( + setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) + + require.Equal(t, 1, len(intermediateCertChildren.CertIds)) + require.Equal(t, + certificateIdentifier(testconstants.LeafSubject, testconstants.LeafSubjectKeyID), + *intermediateCertChildren.CertIds[0]) + + // query leaf certificate + leafCertificate, _ := querySingleApprovedCertificate(setup, testconstants.LeafSubject, testconstants.LeafSubjectKeyID) + require.Equal(t, testconstants.LeafCertPem, leafCertificate.PemCert) + + // check child certificate identifiers of leaf certificate + leafCertChildren, err := queryChildCertificates(setup, testconstants.LeafSubject, testconstants.LeafSubjectKeyID) + require.Error(t, err) + require.Equal(t, codes.NotFound, status.Code(err)) + require.Nil(t, leafCertChildren) +} + +//nolint:funlen +func TestHandler_AddX509Cert_EachChildCertRefersToTwoParentCerts(t *testing.T) { + setup := Setup(t) + + // store root certificate + rootCert := rootCertificate(setup.Trustee1) + + setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCert) + setup.Keeper.SetUniqueCertificate(setup.Ctx, uniqueCertificate(rootCert.Subject, rootCert.SerialNumber)) + + // store second root certificate + rootCert = rootCertificate(setup.Trustee1) + rootCert.SerialNumber = SerialNumber + + setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCert) + setup.Keeper.SetUniqueCertificate(setup.Ctx, uniqueCertificate(rootCert.Subject, rootCert.SerialNumber)) + + // store intermediate certificate (it refers to two parent certificates) + intermediateCertificate := intermediateCertificate(setup.Trustee1) + intermediateCertificate.SerialNumber = SerialNumber + + setup.Keeper.AddApprovedCertificate(setup.Ctx, intermediateCertificate) + setup.Keeper.SetUniqueCertificate( + setup.Ctx, + uniqueCertificate(intermediateCertificate.Issuer, intermediateCertificate.SerialNumber), + ) + + childCertID := certificateIdentifier(intermediateCertificate.Subject, intermediateCertificate.SubjectKeyId) + rootChildCertificates := types.ChildCertificates{ + Issuer: intermediateCertificate.Issuer, + AuthorityKeyId: intermediateCertificate.AuthorityKeyId, + CertIds: []*types.CertificateIdentifier{&childCertID}, + } + setup.Keeper.SetChildCertificates(setup.Ctx, rootChildCertificates) + + // store second intermediate certificate (it refers to two parent certificates) + addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) + _, err := setup.Handler(setup.Ctx, addX509Cert) + require.NoError(t, err) + + // store leaf certificate (it refers to two parent certificates) + addX509Cert = types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.LeafCertPem) + _, err = setup.Handler(setup.Ctx, addX509Cert) + require.NoError(t, err) + + // query root certificate + rootCertificates, _ := queryApprovedCertificates(setup, testconstants.RootSubject, testconstants.RootSubjectKeyID) + require.Equal(t, 2, len(rootCertificates.Certs)) + + // check child certificate identifiers of root certificate + rootCertChildren, _ := queryChildCertificates(setup, testconstants.RootSubject, testconstants.RootSubjectKeyID) + + require.Equal(t, 1, len(rootCertChildren.CertIds)) + require.Equal(t, + certificateIdentifier(testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID), + *rootCertChildren.CertIds[0]) + + // query intermediate certificate + intermediateCertificates, _ := queryApprovedCertificates( + setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) + require.Equal(t, 2, len(intermediateCertificates.Certs)) + + // check child certificate identifiers of intermediate certificate + intermediateCertChildren, _ := queryChildCertificates( + setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) + + require.Equal(t, 1, len(intermediateCertChildren.CertIds)) + require.Equal(t, + certificateIdentifier(testconstants.LeafSubject, testconstants.LeafSubjectKeyID), + *intermediateCertChildren.CertIds[0]) + + // query leaf certificate + leafCertificates, _ := queryApprovedCertificates(setup, testconstants.LeafSubject, testconstants.LeafSubjectKeyID) + require.Equal(t, 1, len(leafCertificates.Certs)) + + // check child certificate identifiers of intermediate certificate + leafCertChildren, err := queryChildCertificates(setup, testconstants.LeafSubject, testconstants.LeafSubjectKeyID) + require.Error(t, err) + require.Equal(t, codes.NotFound, status.Code(err)) + require.Nil(t, leafCertChildren) +} + +func TestHandler_AddX509Cert_ByNotOwner(t *testing.T) { + setup := Setup(t) + + rootCertificate := rootCertificate(setup.Trustee1) + setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCertificate) + + // add an intermidiate certificate from vendor + intermediateCertificate := intermediateCertificate(setup.Trustee1) + intermediateCertificate.SerialNumber = SerialNumber + setup.Keeper.AddApprovedCertificate(setup.Ctx, intermediateCertificate) + setup.Keeper.AddApprovedCertificateBySubjectKeyID(setup.Ctx, intermediateCertificate) + setup.Keeper.SetUniqueCertificate( + setup.Ctx, + uniqueCertificate(intermediateCertificate.Issuer, intermediateCertificate.SerialNumber), + ) + + // add an intermediate certificate with the same subject and SKID from the same vendor but under a different account + addX509Cert := types.NewMsgAddX509Cert(setup.Trustee2.String(), testconstants.IntermediateCertPem) + _, err := setup.Handler(setup.Ctx, addX509Cert) + require.Error(t, err) + require.True(t, sdkerrors.ErrUnauthorized.Is(err)) +} + +func TestHandler_AddX509Cert_ByNotOwnerButSameVendor(t *testing.T) { + setup := Setup(t) + + rootCertificate := rootCertificate(setup.Trustee1) + setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCertificate) + + vendorAccAddress1 := GenerateAccAddress() + setup.AddAccount(vendorAccAddress1, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.Vid) + + // add an intermidiate certificate from vendor + intermediateCertificate := intermediateCertificate(vendorAccAddress1) + intermediateCertificate.SerialNumber = SerialNumber + setup.Keeper.AddApprovedCertificate(setup.Ctx, intermediateCertificate) + setup.Keeper.AddApprovedCertificateBySubjectKeyID(setup.Ctx, intermediateCertificate) + setup.Keeper.SetUniqueCertificate( + setup.Ctx, + uniqueCertificate(intermediateCertificate.Issuer, intermediateCertificate.SerialNumber), + ) + + vendorAccAddress2 := GenerateAccAddress() + setup.AddAccount(vendorAccAddress2, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.Vid) + + // add an intermediate certificate with the same subject and SKID from the same vendor but under a different account + addX509Cert := types.NewMsgAddX509Cert(vendorAccAddress2.String(), testconstants.IntermediateCertPem) + _, err := setup.Handler(setup.Ctx, addX509Cert) + require.NoError(t, err) +} + +func TestHandler_AddX509Cert_ByNotOwnerAndOtherVendor(t *testing.T) { + setup := Setup(t) + + rootCertificate := rootCertificate(setup.Trustee1) + setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCertificate) + + vendorAccAddress1 := GenerateAccAddress() + setup.AddAccount(vendorAccAddress1, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.Vid) + + // add an intermidiate certificate from vendor + intermediateCertificate := intermediateCertificate(vendorAccAddress1) + intermediateCertificate.SerialNumber = SerialNumber + setup.Keeper.AddApprovedCertificate(setup.Ctx, intermediateCertificate) + setup.Keeper.AddApprovedCertificateBySubjectKeyID(setup.Ctx, intermediateCertificate) + setup.Keeper.SetUniqueCertificate( + setup.Ctx, + uniqueCertificate(intermediateCertificate.Issuer, intermediateCertificate.SerialNumber), + ) + + vendorAccAddress2 := GenerateAccAddress() + setup.AddAccount(vendorAccAddress2, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.VendorID1) + + // add an intermediate certificate with the same subject and SKID from the same vendor but under a different account + addX509Cert := types.NewMsgAddX509Cert(vendorAccAddress2.String(), testconstants.IntermediateCertPem) + _, err := setup.Handler(setup.Ctx, addX509Cert) + require.Error(t, err) + require.True(t, sdkerrors.ErrUnauthorized.Is(err)) +} diff --git a/x/pki/handler_revoke_non_root_cert_test.go b/x/pki/handler_revoke_non_root_cert_test.go new file mode 100644 index 000000000..b56a0d941 --- /dev/null +++ b/x/pki/handler_revoke_non_root_cert_test.go @@ -0,0 +1,421 @@ +package pki + +import ( + "testing" + + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/stretchr/testify/require" + testconstants "github.com/zigbee-alliance/distributed-compliance-ledger/integration_tests/constants" + pkitypes "github.com/zigbee-alliance/distributed-compliance-ledger/types/pki" + dclauthtypes "github.com/zigbee-alliance/distributed-compliance-ledger/x/dclauth/types" + "github.com/zigbee-alliance/distributed-compliance-ledger/x/pki/types" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +func TestHandler_RevokeX509CertRoot_CertificateDoesNotExistBySerialNumber(t *testing.T) { + setup := Setup(t) + // propose and approve x509 root certificate + rootCertOptions := createTestRootCertOptions() + proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOptions) + + // revoke x509 certificate + revokeX509Cert := types.NewMsgProposeRevokeX509RootCert( + setup.Trustee1.String(), testconstants.RootSubject, testconstants.RootSubjectKeyID, "invalid", testconstants.Info) + _, err := setup.Handler(setup.Ctx, revokeX509Cert) + require.Error(t, err) + require.True(t, pkitypes.ErrCertificateDoesNotExist.Is(err)) +} +func TestHandler_RevokeX509Cert_CertificateDoesNotExist(t *testing.T) { + setup := Setup(t) + + // revoke x509 certificate + revokeX509Cert := types.NewMsgRevokeX509Cert( + setup.Trustee1.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, testconstants.IntermediateSerialNumber, testconstants.Info) + _, err := setup.Handler(setup.Ctx, revokeX509Cert) + require.Error(t, err) + require.True(t, pkitypes.ErrCertificateDoesNotExist.Is(err)) +} + +func TestHandler_RevokeX509Cert_CertificateDoesNotExistBySerialNumber(t *testing.T) { + setup := Setup(t) + // propose and approve x509 root certificate + rootCertOptions := createTestRootCertOptions() + proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOptions) + + // Add intermediate certificate + addIntermediateX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) + _, err := setup.Handler(setup.Ctx, addIntermediateX509Cert) + require.NoError(t, err) + + // revoke x509 certificate + revokeX509Cert := types.NewMsgRevokeX509Cert( + setup.Trustee1.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, "invalid", testconstants.Info) + _, err = setup.Handler(setup.Ctx, revokeX509Cert) + require.Error(t, err) + require.True(t, pkitypes.ErrCertificateDoesNotExist.Is(err)) +} + +func TestHandler_RevokeX509Cert_ForRootCertificate(t *testing.T) { + setup := Setup(t) + + // propose and approve x509 root certificate + rootCertOptions := createTestRootCertOptions() + proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOptions) + + // revoke x509 root certificate + revokeX509Cert := types.NewMsgRevokeX509Cert( + setup.Trustee1.String(), testconstants.RootSubject, testconstants.RootSubjectKeyID, testconstants.RootSerialNumber, testconstants.Info) + _, err := setup.Handler(setup.Ctx, revokeX509Cert) + require.Error(t, err) + require.True(t, pkitypes.ErrInappropriateCertificateType.Is(err)) +} + +func TestHandler_RevokeX509Cert_ForTree(t *testing.T) { + setup := Setup(t) + + // add root x509 certificate + rootCertOptions := createTestRootCertOptions() + proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOptions) + + // add intermediate x509 certificate + addIntermediateX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) + _, err := setup.Handler(setup.Ctx, addIntermediateX509Cert) + require.NoError(t, err) + + // add leaf x509 certificate + addLeafX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.LeafCertPem) + _, err = setup.Handler(setup.Ctx, addLeafX509Cert) + require.NoError(t, err) + + // check that intermediate nd leaf certificates removed from subject-key-id -> certs map + certs, _ := queryAllApprovedCertificatesBySubjectKeyID(setup, testconstants.IntermediateSubjectKeyID) + require.Equal(t, 1, len(certs)) + certs, _ = queryAllApprovedCertificatesBySubjectKeyID(setup, testconstants.LeafSubjectKeyID) + require.Equal(t, 1, len(certs)) + + // revoke x509 certificate + revokeX509Cert := types.NewMsgRevokeX509Cert( + setup.Trustee1.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, "", testconstants.Info) + _, err = setup.Handler(setup.Ctx, revokeX509Cert) + require.NoError(t, err) + + // check that intermediate and leaf certificates have been revoked + allRevokedCertificates, _ := queryAllRevokedCertificates(setup) + require.Equal(t, 2, len(allRevokedCertificates)) + require.Equal(t, testconstants.LeafSubject, allRevokedCertificates[0].Subject) + require.Equal(t, testconstants.LeafSubjectKeyID, allRevokedCertificates[0].SubjectKeyId) + require.Equal(t, 1, len(allRevokedCertificates[0].Certs)) + require.Equal(t, testconstants.LeafCertPem, allRevokedCertificates[0].Certs[0].PemCert) + require.Equal(t, testconstants.IntermediateSubject, allRevokedCertificates[1].Subject) + require.Equal(t, testconstants.IntermediateSubjectKeyID, allRevokedCertificates[1].SubjectKeyId) + require.Equal(t, 1, len(allRevokedCertificates[1].Certs)) + require.Equal(t, testconstants.IntermediateCertPem, allRevokedCertificates[1].Certs[0].PemCert) + + // check that root certificate stays approved + allApprovedCertificates, _ := queryAllApprovedCertificates(setup) + require.Equal(t, 1, len(allApprovedCertificates)) + require.Equal(t, testconstants.RootSubject, allApprovedCertificates[0].Subject) + require.Equal(t, testconstants.RootSubjectKeyID, allApprovedCertificates[0].SubjectKeyId) + // check that root certificate(by subject key id) stays approved + allApprovedCertificates, _ = queryAllApprovedCertificatesBySubjectKeyID(setup, testconstants.RootSubjectKeyID) + require.Equal(t, 1, len(allApprovedCertificates)) + require.Equal(t, testconstants.RootSubjectKeyID, allApprovedCertificates[0].SubjectKeyId) + // check that intermediate and leaf certificates removed from subject-key-id -> certs map + allApprovedCertificates, _ = queryAllApprovedCertificatesBySubjectKeyID(setup, testconstants.IntermediateSubjectKeyID) + require.Equal(t, 0, len(allApprovedCertificates)) + allApprovedCertificates, _ = queryAllApprovedCertificatesBySubjectKeyID(setup, testconstants.LeafSubjectKeyID) + require.Equal(t, 0, len(allApprovedCertificates)) + + // check that no proposed certificate revocations have been created + allProposedCertificateRevocations, _ := queryAllProposedCertificateRevocations(setup) + require.NoError(t, err) + require.Equal(t, 0, len(allProposedCertificateRevocations)) + + // check that no child certificate identifiers are now registered for root certificate + _, err = queryChildCertificates(setup, testconstants.RootSubject, testconstants.RootSubjectKeyID) + require.Error(t, err) + require.Equal(t, codes.NotFound, status.Code(err)) + + // check that no child certificate identifiers are registered for revoked intermediate certificate + _, err = queryChildCertificates(setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) + require.Error(t, err) + require.Equal(t, codes.NotFound, status.Code(err)) + + // check that no child certificate identifiers are registered for revoked leaf certificate + _, err = queryChildCertificates(setup, testconstants.LeafSubject, testconstants.LeafSubjectKeyID) + require.Error(t, err) + require.Equal(t, codes.NotFound, status.Code(err)) +} + +func TestHandler_RevokeX509Cert_ByNotOwner(t *testing.T) { + setup := Setup(t) + + // store root certificate + rootCertificate := rootCertificate(setup.Trustee1) + setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCertificate) + + // add x509 certificate by `setup.Trustee` + addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) + _, err := setup.Handler(setup.Ctx, addX509Cert) + require.NoError(t, err) + + // store another account + anotherTrustee := GenerateAccAddress() + setup.AddAccount(anotherTrustee, []dclauthtypes.AccountRole{dclauthtypes.Trustee}, 1) + + // revoke x509 certificate by another account + revokeX509Cert := types.NewMsgRevokeX509Cert( + anotherTrustee.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, testconstants.IntermediateSerialNumber, testconstants.Info) + _, err = setup.Handler(setup.Ctx, revokeX509Cert) + require.Error(t, err) + require.True(t, sdkerrors.ErrUnauthorized.Is(err)) +} + +func TestHandler_RevokeX509Cert_ByNotOwnerButSameVendor(t *testing.T) { + setup := Setup(t) + + // store root certificate + rootCertificate := rootCertificate(setup.Trustee1) + setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCertificate) + + // add first vendor's account + vendorAccAddress1 := GenerateAccAddress() + setup.AddAccount(vendorAccAddress1, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.Vid) + + // add x509 certificate by vendor` + addX509Cert := types.NewMsgAddX509Cert(vendorAccAddress1.String(), testconstants.IntermediateCertPem) + _, err := setup.Handler(setup.Ctx, addX509Cert) + require.NoError(t, err) + + // add second vendor's account + vendorAccAddress2 := GenerateAccAddress() + setup.AddAccount(vendorAccAddress2, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.Vid) + + // revoke x509 certificate by another account + revokeX509Cert := types.NewMsgRevokeX509Cert( + vendorAccAddress2.String(), + testconstants.IntermediateSubject, + testconstants.IntermediateSubjectKeyID, + testconstants.IntermediateSerialNumber, + testconstants.Info, + ) + _, err = setup.Handler(setup.Ctx, revokeX509Cert) + require.NoError(t, err) + + // check that intermediate cer + + // check that intermediate certificate has been added to revoked list + revokedCertificates, _ := queryRevokedCertificates(setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) + require.Equal(t, testconstants.IntermediateSubject, revokedCertificates.Subject) + require.Equal(t, testconstants.IntermediateSubjectKeyID, revokedCertificates.SubjectKeyId) + require.Equal(t, 1, len(revokedCertificates.Certs)) + require.Equal(t, intermediateCertificate(vendorAccAddress1), *revokedCertificates.Certs[0]) + + // check that revoked certificate remover from approved certificates list + _, err = queryApprovedCertificates(setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) + require.Error(t, err) + require.Equal(t, codes.NotFound, status.Code(err)) + + // check that revoked certificate removed from approved certificates by subject list + _, err = queryApprovedCertificatesBySubject(setup, testconstants.IntermediateSubject) + require.Error(t, err) + require.Equal(t, codes.NotFound, status.Code(err)) + + // check that revoked certificate removed from approved certificates by SKID list + approvedCerts, err := queryAllApprovedCertificatesBySubjectKeyID(setup, testconstants.IntermediateSubjectKeyID) + require.NoError(t, err) + require.Equal(t, 0, len(approvedCerts)) + + // check that child certificate identifiers list of issuer do not exist anymore + _, err = queryChildCertificates(setup, testconstants.IntermediateIssuer, testconstants.IntermediateAuthorityKeyID) + require.Error(t, err) + require.Equal(t, codes.NotFound, status.Code(err)) + + // check that unique certificate key stays registered + require.True(t, setup.Keeper.IsUniqueCertificatePresent(setup.Ctx, + testconstants.IntermediateIssuer, testconstants.IntermediateSerialNumber)) +} + +func TestHandler_RevokeX509Cert_ByNotOwnerAndOtherVendor(t *testing.T) { + setup := Setup(t) + + // store root certificate + rootCertificate := rootCertificate(setup.Trustee1) + setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCertificate) + + vendorAccAddress1 := GenerateAccAddress() + setup.AddAccount(vendorAccAddress1, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.Vid) + + // add x509 certificate by `setup.Trustee` + addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) + _, err := setup.Handler(setup.Ctx, addX509Cert) + require.NoError(t, err) + + // store another account + anotherTrustee := GenerateAccAddress() + setup.AddAccount(anotherTrustee, []dclauthtypes.AccountRole{dclauthtypes.Trustee}, 1) + + vendorAccAddress2 := GenerateAccAddress() + setup.AddAccount(vendorAccAddress2, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.Vid) + + // revoke x509 certificate by another account + revokeX509Cert := types.NewMsgRevokeX509Cert( + anotherTrustee.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, testconstants.IntermediateSerialNumber, testconstants.Info) + _, err = setup.Handler(setup.Ctx, revokeX509Cert) + require.Error(t, err) + require.True(t, sdkerrors.ErrUnauthorized.Is(err)) +} + +func TestHandler_RevokeX509Cert(t *testing.T) { + setup := Setup(t) + + // store root certificate + rootCertificate := rootCertificate(setup.Trustee1) + setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCertificate) + + for _, role := range []dclauthtypes.AccountRole{ + dclauthtypes.Vendor, + dclauthtypes.CertificationCenter, + dclauthtypes.Trustee, + dclauthtypes.NodeAdmin, + } { + accAddress := GenerateAccAddress() + setup.AddAccount(accAddress, []dclauthtypes.AccountRole{role}, 1) + + // add x509 certificate + addX509Cert := types.NewMsgAddX509Cert(accAddress.String(), testconstants.IntermediateCertPem) + _, err := setup.Handler(setup.Ctx, addX509Cert) + require.NoError(t, err) + + // get intermediate certificate by subject-key-id + certsBySubjectKeyID, _ := queryAllApprovedCertificatesBySubjectKeyID(setup, testconstants.IntermediateSubjectKeyID) + require.Equal(t, 1, len(certsBySubjectKeyID)) + // get certificate for further comparison + certificateBeforeRevocation, _ := querySingleApprovedCertificate( + setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) + require.NotNil(t, certificateBeforeRevocation) + + // revoke x509 certificate + revokeX509Cert := types.NewMsgRevokeX509Cert( + accAddress.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, "", testconstants.Info) + _, err = setup.Handler(setup.Ctx, revokeX509Cert) + require.NoError(t, err) + + // check that intermediate certificate has been revoked + allRevokedCertificates, _ := queryAllRevokedCertificates(setup) + require.Equal(t, 1, len(allRevokedCertificates)) + require.Equal(t, testconstants.IntermediateSubject, allRevokedCertificates[0].Subject) + require.Equal(t, testconstants.IntermediateSubjectKeyID, allRevokedCertificates[0].SubjectKeyId) + require.Equal(t, 1, len(allRevokedCertificates[0].Certs)) + require.Equal(t, *certificateBeforeRevocation, *allRevokedCertificates[0].Certs[0]) + + // check that root certificate stays approved + allApprovedCertificates, _ := queryAllApprovedCertificates(setup) + require.Equal(t, 1, len(allApprovedCertificates)) + require.Equal(t, testconstants.IntermediateSubject, allRevokedCertificates[0].Subject) + require.Equal(t, testconstants.IntermediateSubjectKeyID, allRevokedCertificates[0].SubjectKeyId) + + // check that intermediate certificate removed from subject-key-id -> certs map + certsBySubjectKeyID, _ = queryAllApprovedCertificatesBySubjectKeyID(setup, testconstants.IntermediateSubjectKeyID) + require.Equal(t, 0, len(certsBySubjectKeyID)) + + // check that no proposed certificate revocations have been created + allProposedCertificateRevocations, _ := queryAllProposedCertificateRevocations(setup) + require.NoError(t, err) + require.Equal(t, 0, len(allProposedCertificateRevocations)) + + // check that child certificate identifiers list of issuer do not exist anymore + _, err = queryChildCertificates(setup, testconstants.IntermediateIssuer, testconstants.IntermediateAuthorityKeyID) + require.Error(t, err) + require.Equal(t, codes.NotFound, status.Code(err)) + + // check that unique certificate key stays registered + require.True(t, setup.Keeper.IsUniqueCertificatePresent(setup.Ctx, + testconstants.IntermediateIssuer, testconstants.IntermediateSerialNumber)) + + // cleanup for next iteration + setup.Keeper.RemoveRevokedCertificates(setup.Ctx, + testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) + setup.Keeper.RemoveUniqueCertificate(setup.Ctx, + testconstants.IntermediateIssuer, testconstants.IntermediateSerialNumber) + } +} + +func TestHandler_RevokeX509Cert_BySerialNumber(t *testing.T) { + setup := Setup(t) + // propose and approve x509 root certificate + rootCertOptions := createTestRootCertOptions() + proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOptions) + + // Add two intermediate certificates + addIntermediateX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) + _, err := setup.Handler(setup.Ctx, addIntermediateX509Cert) + require.NoError(t, err) + intermediateCertificate := intermediateCertificate(setup.Trustee1) + intermediateCertificate.SerialNumber = SerialNumber + setup.Keeper.AddApprovedCertificate(setup.Ctx, intermediateCertificate) + setup.Keeper.AddApprovedCertificateBySubjectKeyID(setup.Ctx, intermediateCertificate) + setup.Keeper.SetUniqueCertificate( + setup.Ctx, + uniqueCertificate(intermediateCertificate.Issuer, intermediateCertificate.SerialNumber), + ) + // Add a leaf certificate + addLeafX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.LeafCertPem) + _, err = setup.Handler(setup.Ctx, addLeafX509Cert) + require.NoError(t, err) + + // get certificates for further comparison + allCerts := setup.Keeper.GetAllApprovedCertificates(setup.Ctx) + require.NotNil(t, allCerts) + require.Equal(t, 3, len(allCerts)) + require.Equal(t, 4, len(allCerts[0].Certs)+len(allCerts[1].Certs)+len(allCerts[2].Certs)) + + // revoke intermediate certificate + revokeX509Cert := types.NewMsgRevokeX509Cert( + setup.Trustee1.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, testconstants.IntermediateSerialNumber, testconstants.Info) + _, err = setup.Handler(setup.Ctx, revokeX509Cert) + require.NoError(t, err) + + // check that proposed certificate revocation does not exist anymore + _, err = queryProposedCertificateRevocation(setup, testconstants.IntermediateSerialNumber) + require.Error(t, err) + require.Equal(t, codes.NotFound, status.Code(err)) + + // check that only root and two intermediate certificates exists + allCerts, _ = queryAllApprovedCertificates(setup) + require.Equal(t, 3, len(allCerts)) + require.Equal(t, 3, len(allCerts[0].Certs)+len(allCerts[1].Certs)+len(allCerts[2].Certs)) + intermediateCerts, _ := queryApprovedCertificates(setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) + require.Equal(t, 1, len(intermediateCerts.Certs)) + require.Equal(t, SerialNumber, intermediateCerts.Certs[0].SerialNumber) + + // query and check revoked certificate + revokedCertificate, _ := querySingleRevokedCertificate(setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) + require.NotNil(t, revokedCertificate) + require.Equal(t, testconstants.IntermediateSubject, revokedCertificate.Subject) + require.Equal(t, testconstants.IntermediateSubjectKeyID, revokedCertificate.SubjectKeyId) + require.Equal(t, testconstants.IntermediateSerialNumber, revokedCertificate.SerialNumber) + + // revoke intermediate certificate + revokeX509Cert = types.NewMsgRevokeX509Cert( + setup.Trustee1.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, SerialNumber, testconstants.Info) + _, err = setup.Handler(setup.Ctx, revokeX509Cert) + require.NoError(t, err) + + _, err = queryProposedCertificateRevocation(setup, testconstants.IntermediateSerialNumber) + require.Error(t, err) + require.Equal(t, codes.NotFound, status.Code(err)) + + // check that only root certificate exists + certsAfterRevocation := setup.Keeper.GetAllApprovedCertificates(setup.Ctx) + require.Equal(t, 1, len(certsAfterRevocation)) + require.Equal(t, 1, len(certsAfterRevocation[0].Certs)) + require.Equal(t, testconstants.RootSerialNumber, certsAfterRevocation[0].Certs[0].SerialNumber) + + // query and check revoked certificate + revokedCerts, _ := queryRevokedCertificates(setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) + require.Equal(t, 2, len(revokedCerts.Certs)) + require.Equal(t, testconstants.IntermediateSubject, revokedCerts.Subject) + require.Equal(t, testconstants.IntermediateSubjectKeyID, revokedCerts.SubjectKeyId) +} diff --git a/x/pki/handler_test.go b/x/pki/handler_test.go index c7f094cd7..d3524c498 100644 --- a/x/pki/handler_test.go +++ b/x/pki/handler_test.go @@ -712,388 +712,6 @@ func TestHandler_AddX509RootCertsBySubjectKeyId(t *testing.T) { require.Equal(t, testconstants.PAACertWithSameSubjectID2Subject, approvedCertificates[0].Certs[1].Subject) } -func TestHandler_AddX509Cert(t *testing.T) { - setup := Setup(t) - - // store root certificate - rootCertificate := rootCertificate(setup.Trustee1) - setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCertificate) - - for i, role := range []dclauthtypes.AccountRole{ - dclauthtypes.Vendor, - dclauthtypes.CertificationCenter, - dclauthtypes.Trustee, - dclauthtypes.NodeAdmin, - } { - accAddress := GenerateAccAddress() - setup.AddAccount(accAddress, []dclauthtypes.AccountRole{role}, 1) - - // add x509 certificate - addX509Cert := types.NewMsgAddX509Cert(accAddress.String(), testconstants.IntermediateCertPem) - _, err := setup.Handler(setup.Ctx, addX509Cert) - require.NoError(t, err) - - // query certificate - certificate, _ := querySingleApprovedCertificate( - setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) - - certificateBySubjectKeyID, _ := queryAllApprovedCertificatesBySubjectKeyID(setup, testconstants.IntermediateSubjectKeyID) - require.Equal(t, 1, len(certificateBySubjectKeyID)) - require.Equal(t, i+1, len(certificateBySubjectKeyID[0].Certs)) - - certs := make([]*types.Certificate, 0) - certs = append(certs, certificate, certificateBySubjectKeyID[0].Certs[i]) - for _, cert := range certs { - // check - require.Equal(t, addX509Cert.Cert, cert.PemCert) - require.Equal(t, addX509Cert.Signer, cert.Owner) - require.Equal(t, testconstants.IntermediateSubject, cert.Subject) - require.Equal(t, testconstants.IntermediateSubjectKeyID, cert.SubjectKeyId) - require.Equal(t, testconstants.IntermediateSerialNumber, cert.SerialNumber) - require.False(t, cert.IsRoot) - require.Equal(t, testconstants.IntermediateIssuer, cert.Issuer) - require.Equal(t, testconstants.IntermediateAuthorityKeyID, cert.AuthorityKeyId) - require.Equal(t, testconstants.RootSubject, cert.RootSubject) - require.Equal(t, testconstants.RootSubjectKeyID, cert.RootSubjectKeyId) - } - - // check that unique certificate key is registered - require.True(t, setup.Keeper.IsUniqueCertificatePresent( - setup.Ctx, testconstants.IntermediateIssuer, testconstants.IntermediateSerialNumber)) - - // check that child certificates of issuer contains certificate identifier - issuerChildren, _ := queryChildCertificates( - setup, testconstants.IntermediateIssuer, testconstants.IntermediateAuthorityKeyID) - require.Equal(t, 1, len(issuerChildren.CertIds)) - require.Equal(t, - &types.CertificateIdentifier{ - Subject: testconstants.IntermediateSubject, - SubjectKeyId: testconstants.IntermediateSubjectKeyID, - }, - issuerChildren.CertIds[0]) - - // check that no proposed certificate has been created - _, err = queryProposedCertificate(setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) - require.Error(t, err) - require.Equal(t, codes.NotFound, status.Code(err)) - - // cleanup for next iteration - setup.Keeper.RemoveApprovedCertificates(setup.Ctx, - testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) - setup.Keeper.RemoveUniqueCertificate(setup.Ctx, - testconstants.IntermediateIssuer, testconstants.IntermediateSerialNumber) - setup.Keeper.RemoveChildCertificates(setup.Ctx, - testconstants.IntermediateIssuer, testconstants.IntermediateAuthorityKeyID) - } -} - -func TestHandler_AddX509Cert_ForInvalidCertificate(t *testing.T) { - setup := Setup(t) - - // add x509 certificate - addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.StubCertPem) - _, err := setup.Handler(setup.Ctx, addX509Cert) - require.Error(t, err) - require.True(t, pkitypes.ErrInvalidCertificate.Is(err)) -} - -func TestHandler_AddX509Cert_ForRootCertificate(t *testing.T) { - setup := Setup(t) - - // add root certificate as leaf x509 certificate - addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.RootCertPem) - _, err := setup.Handler(setup.Ctx, addX509Cert) - require.Error(t, err) - require.True(t, pkitypes.ErrInappropriateCertificateType.Is(err)) -} - -func TestHandler_AddX509Cert_ForDuplicate(t *testing.T) { - setup := Setup(t) - - // store root certificate - rootCertificate := rootCertificate(setup.Trustee1) - setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCertificate) - - // store intermediate certificate - addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) - _, err := setup.Handler(setup.Ctx, addX509Cert) - require.NoError(t, err) - - // store intermediate certificate second time - _, err = setup.Handler(setup.Ctx, addX509Cert) - require.Error(t, err) - require.True(t, pkitypes.ErrCertificateAlreadyExists.Is(err)) -} - -func TestHandler_AddX509Cert_ForNocCertificate(t *testing.T) { - setup := Setup(t) - - // store root certificate - rootCertificate := rootCertificate(setup.Trustee1) - setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCertificate) - - // Store the NOC certificate - vendorAccAddress := GenerateAccAddress() - setup.AddAccount(vendorAccAddress, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.Vid) - - nocCertificate := intermediateCertificate(vendorAccAddress) - nocCertificate.SerialNumber = testconstants.TestSerialNumber - nocCertificate.IsNoc = true - - setup.Keeper.AddApprovedCertificate(setup.Ctx, nocCertificate) - // TODO: add the certificate to the ICA store after the store is implemented - uniqueCertificate := types.UniqueCertificate{ - Issuer: nocCertificate.Issuer, - SerialNumber: nocCertificate.SerialNumber, - Present: true, - } - setup.Keeper.SetUniqueCertificate(setup.Ctx, uniqueCertificate) - - // store intermediate certificate - addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) - _, err := setup.Handler(setup.Ctx, addX509Cert) - require.True(t, pkitypes.ErrInappropriateCertificateType.Is(err)) -} - -func TestHandler_AddX509Cert_ForDifferentSerialNumber(t *testing.T) { - setup := Setup(t) - - // store root certificate - rootCertificate := rootCertificate(setup.Trustee1) - setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCertificate) - - // store intermediate certificate with different serial number - intermediateCertificate := intermediateCertificate(setup.Trustee1) - intermediateCertificate.SerialNumber = SerialNumber - setup.Keeper.SetUniqueCertificate( - setup.Ctx, - uniqueCertificate(intermediateCertificate.Issuer, intermediateCertificate.SerialNumber), - ) - setup.Keeper.AddApprovedCertificate(setup.Ctx, intermediateCertificate) - - // store intermediate certificate second time - addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) - _, err := setup.Handler(setup.Ctx, addX509Cert) - require.NoError(t, err) - - // query certificate - certificates, _ := queryApprovedCertificates(setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) - - // check - require.Equal(t, 2, len(certificates.Certs)) - require.NotEqual(t, certificates.Certs[0].SerialNumber, certificates.Certs[1].SerialNumber) - - for _, certificate := range certificates.Certs { - require.Equal(t, addX509Cert.Cert, certificate.PemCert) - require.Equal(t, addX509Cert.Signer, certificate.Owner) - require.Equal(t, testconstants.IntermediateSubject, certificate.Subject) - require.Equal(t, testconstants.IntermediateSubjectKeyID, certificate.SubjectKeyId) - require.False(t, certificate.IsRoot) - require.Equal(t, testconstants.RootSubject, certificate.RootSubject) - require.Equal(t, testconstants.RootSubjectKeyID, certificate.RootSubjectKeyId) - require.Equal(t, testconstants.IntermediateIssuer, certificate.Issuer) - require.Equal(t, testconstants.IntermediateAuthorityKeyID, certificate.AuthorityKeyId) - } -} - -func TestHandler_AddX509Cert_ForDifferentSerialNumberDifferentSigner(t *testing.T) { - setup := Setup(t) - - // store root certificate - rootCertificate := rootCertificate(testconstants.Address1) - setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCertificate) - - // store intermediate certificate with different serial number - intermediateCertificate := intermediateCertificate(testconstants.Address1) - intermediateCertificate.SerialNumber = SerialNumber - setup.Keeper.SetUniqueCertificate( - setup.Ctx, - uniqueCertificate(intermediateCertificate.Issuer, intermediateCertificate.SerialNumber), - ) - setup.Keeper.AddApprovedCertificate(setup.Ctx, intermediateCertificate) - - // store intermediate certificate second time - addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) - _, err := setup.Handler(setup.Ctx, addX509Cert) - require.Error(t, err) - require.True(t, sdkerrors.ErrUnauthorized.Is(err)) -} - -func TestHandler_AddX509Cert_ForAbsentDirectParentCert(t *testing.T) { - setup := Setup(t) - - // add intermediate x509 certificate - addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) - _, err := setup.Handler(setup.Ctx, addX509Cert) - require.Error(t, err) - require.True(t, pkitypes.ErrInvalidCertificate.Is(err)) -} - -func TestHandler_AddX509Cert_ForNoRootCert(t *testing.T) { - setup := Setup(t) - - // add intermediate certificate - intermediateCertificate := intermediateCertificate(setup.Trustee1) - setup.Keeper.AddApprovedCertificate(setup.Ctx, intermediateCertificate) - - // add leaf x509 certificate - addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.LeafCertPem) - _, err := setup.Handler(setup.Ctx, addX509Cert) - require.Error(t, err) - require.True(t, pkitypes.ErrInvalidCertificate.Is(err)) -} - -func TestHandler_AddX509Cert_ForFailedCertificateVerification(t *testing.T) { - setup := Setup(t) - - // add invalid root - invalidRootCertificate := types.NewRootCertificate(testconstants.StubCertPem, - testconstants.RootSubject, testconstants.RootSubjectAsText, testconstants.RootSubjectKeyID, - testconstants.RootSerialNumber, setup.Trustee1.String(), []*types.Grant{}, []*types.Grant{}, testconstants.Vid) - setup.Keeper.AddApprovedCertificate(setup.Ctx, invalidRootCertificate) - - // add intermediate x509 certificate - addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) - _, err := setup.Handler(setup.Ctx, addX509Cert) - require.Error(t, err) - require.True(t, pkitypes.ErrInvalidCertificate.Is(err)) -} - -func TestHandler_AddX509Cert_ForTree(t *testing.T) { - setup := Setup(t) - - // add root x509 certificate - rootCertOptions := createTestRootCertOptions() - proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOptions) - - // add intermediate x509 certificate - addIntermediateX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) - _, err := setup.Handler(setup.Ctx, addIntermediateX509Cert) - require.NoError(t, err) - - // add leaf x509 certificate - addLeafX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.LeafCertPem) - _, err = setup.Handler(setup.Ctx, addLeafX509Cert) - require.NoError(t, err) - - // query root certificate - rootCertificate, _ := querySingleApprovedCertificate(setup, testconstants.RootSubject, testconstants.RootSubjectKeyID) - require.Equal(t, testconstants.RootCertPem, rootCertificate.PemCert) - - // check child certificate identifiers of root certificate - rootCertChildren, _ := queryChildCertificates(setup, testconstants.RootSubject, testconstants.RootSubjectKeyID) - - require.Equal(t, 1, len(rootCertChildren.CertIds)) - require.Equal(t, - certificateIdentifier(testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID), - *rootCertChildren.CertIds[0]) - - // query intermediate certificate - intermediateCertificate, _ := querySingleApprovedCertificate(setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) - require.Equal(t, testconstants.IntermediateCertPem, intermediateCertificate.PemCert) - - // check child certificate identifiers of intermediate certificate - intermediateCertChildren, _ := queryChildCertificates( - setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) - - require.Equal(t, 1, len(intermediateCertChildren.CertIds)) - require.Equal(t, - certificateIdentifier(testconstants.LeafSubject, testconstants.LeafSubjectKeyID), - *intermediateCertChildren.CertIds[0]) - - // query leaf certificate - leafCertificate, _ := querySingleApprovedCertificate(setup, testconstants.LeafSubject, testconstants.LeafSubjectKeyID) - require.Equal(t, testconstants.LeafCertPem, leafCertificate.PemCert) - - // check child certificate identifiers of leaf certificate - leafCertChildren, err := queryChildCertificates(setup, testconstants.LeafSubject, testconstants.LeafSubjectKeyID) - require.Error(t, err) - require.Equal(t, codes.NotFound, status.Code(err)) - require.Nil(t, leafCertChildren) -} - -//nolint:funlen -func TestHandler_AddX509Cert_EachChildCertRefersToTwoParentCerts(t *testing.T) { - setup := Setup(t) - - // store root certificate - rootCert := rootCertificate(setup.Trustee1) - - setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCert) - setup.Keeper.SetUniqueCertificate(setup.Ctx, uniqueCertificate(rootCert.Subject, rootCert.SerialNumber)) - - // store second root certificate - rootCert = rootCertificate(setup.Trustee1) - rootCert.SerialNumber = SerialNumber - - setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCert) - setup.Keeper.SetUniqueCertificate(setup.Ctx, uniqueCertificate(rootCert.Subject, rootCert.SerialNumber)) - - // store intermediate certificate (it refers to two parent certificates) - intermediateCertificate := intermediateCertificate(setup.Trustee1) - intermediateCertificate.SerialNumber = SerialNumber - - setup.Keeper.AddApprovedCertificate(setup.Ctx, intermediateCertificate) - setup.Keeper.SetUniqueCertificate( - setup.Ctx, - uniqueCertificate(intermediateCertificate.Issuer, intermediateCertificate.SerialNumber), - ) - - childCertID := certificateIdentifier(intermediateCertificate.Subject, intermediateCertificate.SubjectKeyId) - rootChildCertificates := types.ChildCertificates{ - Issuer: intermediateCertificate.Issuer, - AuthorityKeyId: intermediateCertificate.AuthorityKeyId, - CertIds: []*types.CertificateIdentifier{&childCertID}, - } - setup.Keeper.SetChildCertificates(setup.Ctx, rootChildCertificates) - - // store second intermediate certificate (it refers to two parent certificates) - addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) - _, err := setup.Handler(setup.Ctx, addX509Cert) - require.NoError(t, err) - - // store leaf certificate (it refers to two parent certificates) - addX509Cert = types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.LeafCertPem) - _, err = setup.Handler(setup.Ctx, addX509Cert) - require.NoError(t, err) - - // query root certificate - rootCertificates, _ := queryApprovedCertificates(setup, testconstants.RootSubject, testconstants.RootSubjectKeyID) - require.Equal(t, 2, len(rootCertificates.Certs)) - - // check child certificate identifiers of root certificate - rootCertChildren, _ := queryChildCertificates(setup, testconstants.RootSubject, testconstants.RootSubjectKeyID) - - require.Equal(t, 1, len(rootCertChildren.CertIds)) - require.Equal(t, - certificateIdentifier(testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID), - *rootCertChildren.CertIds[0]) - - // query intermediate certificate - intermediateCertificates, _ := queryApprovedCertificates( - setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) - require.Equal(t, 2, len(intermediateCertificates.Certs)) - - // check child certificate identifiers of intermediate certificate - intermediateCertChildren, _ := queryChildCertificates( - setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) - - require.Equal(t, 1, len(intermediateCertChildren.CertIds)) - require.Equal(t, - certificateIdentifier(testconstants.LeafSubject, testconstants.LeafSubjectKeyID), - *intermediateCertChildren.CertIds[0]) - - // query leaf certificate - leafCertificates, _ := queryApprovedCertificates(setup, testconstants.LeafSubject, testconstants.LeafSubjectKeyID) - require.Equal(t, 1, len(leafCertificates.Certs)) - - // check child certificate identifiers of intermediate certificate - leafCertChildren, err := queryChildCertificates(setup, testconstants.LeafSubject, testconstants.LeafSubjectKeyID) - require.Error(t, err) - require.Equal(t, codes.NotFound, status.Code(err)) - require.Nil(t, leafCertChildren) -} - func TestHandler_ProposeRevokeX509RootCert_ByTrusteeOwner(t *testing.T) { setup := Setup(t) @@ -1581,159 +1199,6 @@ func TestHandler_ApproveRevokeX509RootCert_ForTree(t *testing.T) { require.Nil(t, leafCertChildren) } -func TestHandler_RevokeX509Cert(t *testing.T) { - setup := Setup(t) - - // store root certificate - rootCertificate := rootCertificate(setup.Trustee1) - setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCertificate) - - for _, role := range []dclauthtypes.AccountRole{ - dclauthtypes.Vendor, - dclauthtypes.CertificationCenter, - dclauthtypes.Trustee, - dclauthtypes.NodeAdmin, - } { - accAddress := GenerateAccAddress() - setup.AddAccount(accAddress, []dclauthtypes.AccountRole{role}, 1) - - // add x509 certificate - addX509Cert := types.NewMsgAddX509Cert(accAddress.String(), testconstants.IntermediateCertPem) - _, err := setup.Handler(setup.Ctx, addX509Cert) - require.NoError(t, err) - - // get intermediate certificate by subject-key-id - certsBySubjectKeyID, _ := queryAllApprovedCertificatesBySubjectKeyID(setup, testconstants.IntermediateSubjectKeyID) - require.Equal(t, 1, len(certsBySubjectKeyID)) - // get certificate for further comparison - certificateBeforeRevocation, _ := querySingleApprovedCertificate( - setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) - require.NotNil(t, certificateBeforeRevocation) - - // revoke x509 certificate - revokeX509Cert := types.NewMsgRevokeX509Cert( - accAddress.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, "", testconstants.Info) - _, err = setup.Handler(setup.Ctx, revokeX509Cert) - require.NoError(t, err) - - // check that intermediate certificate has been revoked - allRevokedCertificates, _ := queryAllRevokedCertificates(setup) - require.Equal(t, 1, len(allRevokedCertificates)) - require.Equal(t, testconstants.IntermediateSubject, allRevokedCertificates[0].Subject) - require.Equal(t, testconstants.IntermediateSubjectKeyID, allRevokedCertificates[0].SubjectKeyId) - require.Equal(t, 1, len(allRevokedCertificates[0].Certs)) - require.Equal(t, *certificateBeforeRevocation, *allRevokedCertificates[0].Certs[0]) - - // check that root certificate stays approved - allApprovedCertificates, _ := queryAllApprovedCertificates(setup) - require.Equal(t, 1, len(allApprovedCertificates)) - require.Equal(t, testconstants.IntermediateSubject, allRevokedCertificates[0].Subject) - require.Equal(t, testconstants.IntermediateSubjectKeyID, allRevokedCertificates[0].SubjectKeyId) - - // check that intermediate certificate removed from subject-key-id -> certs map - certsBySubjectKeyID, _ = queryAllApprovedCertificatesBySubjectKeyID(setup, testconstants.IntermediateSubjectKeyID) - require.Equal(t, 0, len(certsBySubjectKeyID)) - - // check that no proposed certificate revocations have been created - allProposedCertificateRevocations, _ := queryAllProposedCertificateRevocations(setup) - require.NoError(t, err) - require.Equal(t, 0, len(allProposedCertificateRevocations)) - - // check that child certificate identifiers list of issuer do not exist anymore - _, err = queryChildCertificates(setup, testconstants.IntermediateIssuer, testconstants.IntermediateAuthorityKeyID) - require.Error(t, err) - require.Equal(t, codes.NotFound, status.Code(err)) - - // check that unique certificate key stays registered - require.True(t, setup.Keeper.IsUniqueCertificatePresent(setup.Ctx, - testconstants.IntermediateIssuer, testconstants.IntermediateSerialNumber)) - - // cleanup for next iteration - setup.Keeper.RemoveRevokedCertificates(setup.Ctx, - testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) - setup.Keeper.RemoveUniqueCertificate(setup.Ctx, - testconstants.IntermediateIssuer, testconstants.IntermediateSerialNumber) - } -} - -func TestHandler_RevokeX509Cert_BySerialNumber(t *testing.T) { - setup := Setup(t) - // propose and approve x509 root certificate - rootCertOptions := createTestRootCertOptions() - proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOptions) - - // Add two intermediate certificates - addIntermediateX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) - _, err := setup.Handler(setup.Ctx, addIntermediateX509Cert) - require.NoError(t, err) - intermediateCertificate := intermediateCertificate(setup.Trustee1) - intermediateCertificate.SerialNumber = SerialNumber - setup.Keeper.AddApprovedCertificate(setup.Ctx, intermediateCertificate) - setup.Keeper.AddApprovedCertificateBySubjectKeyID(setup.Ctx, intermediateCertificate) - setup.Keeper.SetUniqueCertificate( - setup.Ctx, - uniqueCertificate(intermediateCertificate.Issuer, intermediateCertificate.SerialNumber), - ) - // Add a leaf certificate - addLeafX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.LeafCertPem) - _, err = setup.Handler(setup.Ctx, addLeafX509Cert) - require.NoError(t, err) - - // get certificates for further comparison - allCerts := setup.Keeper.GetAllApprovedCertificates(setup.Ctx) - require.NotNil(t, allCerts) - require.Equal(t, 3, len(allCerts)) - require.Equal(t, 4, len(allCerts[0].Certs)+len(allCerts[1].Certs)+len(allCerts[2].Certs)) - - // revoke intermediate certificate - revokeX509Cert := types.NewMsgRevokeX509Cert( - setup.Trustee1.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, testconstants.IntermediateSerialNumber, testconstants.Info) - _, err = setup.Handler(setup.Ctx, revokeX509Cert) - require.NoError(t, err) - - // check that proposed certificate revocation does not exist anymore - _, err = queryProposedCertificateRevocation(setup, testconstants.IntermediateSerialNumber) - require.Error(t, err) - require.Equal(t, codes.NotFound, status.Code(err)) - - // check that only root and two intermediate certificates exists - allCerts, _ = queryAllApprovedCertificates(setup) - require.Equal(t, 3, len(allCerts)) - require.Equal(t, 3, len(allCerts[0].Certs)+len(allCerts[1].Certs)+len(allCerts[2].Certs)) - intermediateCerts, _ := queryApprovedCertificates(setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) - require.Equal(t, 1, len(intermediateCerts.Certs)) - require.Equal(t, SerialNumber, intermediateCerts.Certs[0].SerialNumber) - - // query and check revoked certificate - revokedCertificate, _ := querySingleRevokedCertificate(setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) - require.NotNil(t, revokedCertificate) - require.Equal(t, testconstants.IntermediateSubject, revokedCertificate.Subject) - require.Equal(t, testconstants.IntermediateSubjectKeyID, revokedCertificate.SubjectKeyId) - require.Equal(t, testconstants.IntermediateSerialNumber, revokedCertificate.SerialNumber) - - // revoke intermediate certificate - revokeX509Cert = types.NewMsgRevokeX509Cert( - setup.Trustee1.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, SerialNumber, testconstants.Info) - _, err = setup.Handler(setup.Ctx, revokeX509Cert) - require.NoError(t, err) - - _, err = queryProposedCertificateRevocation(setup, testconstants.IntermediateSerialNumber) - require.Error(t, err) - require.Equal(t, codes.NotFound, status.Code(err)) - - // check that only root certificate exists - certsAfterRevocation := setup.Keeper.GetAllApprovedCertificates(setup.Ctx) - require.Equal(t, 1, len(certsAfterRevocation)) - require.Equal(t, 1, len(certsAfterRevocation[0].Certs)) - require.Equal(t, testconstants.RootSerialNumber, certsAfterRevocation[0].Certs[0].SerialNumber) - - // query and check revoked certificate - revokedCerts, _ := queryRevokedCertificates(setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) - require.Equal(t, 2, len(revokedCerts.Certs)) - require.Equal(t, testconstants.IntermediateSubject, revokedCerts.Subject) - require.Equal(t, testconstants.IntermediateSubjectKeyID, revokedCerts.SubjectKeyId) -} - func TestHandler_RemoveX509Cert_BySubjectAndSKID(t *testing.T) { setup := Setup(t) // propose and approve x509 root certificate @@ -2130,165 +1595,6 @@ func TestHandler_RevokeX509RootCertsBySubjectKeyId(t *testing.T) { require.Equal(t, 0, len(allProposedCertificateRevocations)) } -func TestHandler_RevokeX509CertRoot_CertificateDoesNotExistBySerialNumber(t *testing.T) { - setup := Setup(t) - // propose and approve x509 root certificate - rootCertOptions := createTestRootCertOptions() - proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOptions) - - // revoke x509 certificate - revokeX509Cert := types.NewMsgProposeRevokeX509RootCert( - setup.Trustee1.String(), testconstants.RootSubject, testconstants.RootSubjectKeyID, "invalid", testconstants.Info) - _, err := setup.Handler(setup.Ctx, revokeX509Cert) - require.Error(t, err) - require.True(t, pkitypes.ErrCertificateDoesNotExist.Is(err)) -} -func TestHandler_RevokeX509Cert_CertificateDoesNotExist(t *testing.T) { - setup := Setup(t) - - // revoke x509 certificate - revokeX509Cert := types.NewMsgRevokeX509Cert( - setup.Trustee1.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, testconstants.IntermediateSerialNumber, testconstants.Info) - _, err := setup.Handler(setup.Ctx, revokeX509Cert) - require.Error(t, err) - require.True(t, pkitypes.ErrCertificateDoesNotExist.Is(err)) -} - -func TestHandler_RevokeX509Cert_CertificateDoesNotExistBySerialNumber(t *testing.T) { - setup := Setup(t) - // propose and approve x509 root certificate - rootCertOptions := createTestRootCertOptions() - proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOptions) - - // Add intermediate certificate - addIntermediateX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) - _, err := setup.Handler(setup.Ctx, addIntermediateX509Cert) - require.NoError(t, err) - - // revoke x509 certificate - revokeX509Cert := types.NewMsgRevokeX509Cert( - setup.Trustee1.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, "invalid", testconstants.Info) - _, err = setup.Handler(setup.Ctx, revokeX509Cert) - require.Error(t, err) - require.True(t, pkitypes.ErrCertificateDoesNotExist.Is(err)) -} - -func TestHandler_RevokeX509Cert_ForRootCertificate(t *testing.T) { - setup := Setup(t) - - // propose and approve x509 root certificate - rootCertOptions := createTestRootCertOptions() - proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOptions) - - // revoke x509 root certificate - revokeX509Cert := types.NewMsgRevokeX509Cert( - setup.Trustee1.String(), testconstants.RootSubject, testconstants.RootSubjectKeyID, testconstants.RootSerialNumber, testconstants.Info) - _, err := setup.Handler(setup.Ctx, revokeX509Cert) - require.Error(t, err) - require.True(t, pkitypes.ErrInappropriateCertificateType.Is(err)) -} - -func TestHandler_RevokeX509Cert_ByNotOwner(t *testing.T) { - setup := Setup(t) - - // store root certificate - rootCertificate := rootCertificate(setup.Trustee1) - setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCertificate) - - // add x509 certificate by `setup.Trustee` - addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) - _, err := setup.Handler(setup.Ctx, addX509Cert) - require.NoError(t, err) - - // store another account - anotherTrustee := GenerateAccAddress() - setup.AddAccount(anotherTrustee, []dclauthtypes.AccountRole{dclauthtypes.Trustee}, 1) - - // revoke x509 certificate by another account - revokeX509Cert := types.NewMsgRevokeX509Cert( - anotherTrustee.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, testconstants.IntermediateSerialNumber, testconstants.Info) - _, err = setup.Handler(setup.Ctx, revokeX509Cert) - require.Error(t, err) - require.True(t, sdkerrors.ErrUnauthorized.Is(err)) -} - -func TestHandler_RevokeX509Cert_ForTree(t *testing.T) { - setup := Setup(t) - - // add root x509 certificate - rootCertOptions := createTestRootCertOptions() - proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOptions) - - // add intermediate x509 certificate - addIntermediateX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) - _, err := setup.Handler(setup.Ctx, addIntermediateX509Cert) - require.NoError(t, err) - - // add leaf x509 certificate - addLeafX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.LeafCertPem) - _, err = setup.Handler(setup.Ctx, addLeafX509Cert) - require.NoError(t, err) - - // check that intermediate nd leaf certificates removed from subject-key-id -> certs map - certs, _ := queryAllApprovedCertificatesBySubjectKeyID(setup, testconstants.IntermediateSubjectKeyID) - require.Equal(t, 1, len(certs)) - certs, _ = queryAllApprovedCertificatesBySubjectKeyID(setup, testconstants.LeafSubjectKeyID) - require.Equal(t, 1, len(certs)) - - // revoke x509 certificate - revokeX509Cert := types.NewMsgRevokeX509Cert( - setup.Trustee1.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, "", testconstants.Info) - _, err = setup.Handler(setup.Ctx, revokeX509Cert) - require.NoError(t, err) - - // check that intermediate and leaf certificates have been revoked - allRevokedCertificates, _ := queryAllRevokedCertificates(setup) - require.Equal(t, 2, len(allRevokedCertificates)) - require.Equal(t, testconstants.LeafSubject, allRevokedCertificates[0].Subject) - require.Equal(t, testconstants.LeafSubjectKeyID, allRevokedCertificates[0].SubjectKeyId) - require.Equal(t, 1, len(allRevokedCertificates[0].Certs)) - require.Equal(t, testconstants.LeafCertPem, allRevokedCertificates[0].Certs[0].PemCert) - require.Equal(t, testconstants.IntermediateSubject, allRevokedCertificates[1].Subject) - require.Equal(t, testconstants.IntermediateSubjectKeyID, allRevokedCertificates[1].SubjectKeyId) - require.Equal(t, 1, len(allRevokedCertificates[1].Certs)) - require.Equal(t, testconstants.IntermediateCertPem, allRevokedCertificates[1].Certs[0].PemCert) - - // check that root certificate stays approved - allApprovedCertificates, _ := queryAllApprovedCertificates(setup) - require.Equal(t, 1, len(allApprovedCertificates)) - require.Equal(t, testconstants.RootSubject, allApprovedCertificates[0].Subject) - require.Equal(t, testconstants.RootSubjectKeyID, allApprovedCertificates[0].SubjectKeyId) - // check that root certificate(by subject key id) stays approved - allApprovedCertificates, _ = queryAllApprovedCertificatesBySubjectKeyID(setup, testconstants.RootSubjectKeyID) - require.Equal(t, 1, len(allApprovedCertificates)) - require.Equal(t, testconstants.RootSubjectKeyID, allApprovedCertificates[0].SubjectKeyId) - // check that intermediate and leaf certificates removed from subject-key-id -> certs map - allApprovedCertificates, _ = queryAllApprovedCertificatesBySubjectKeyID(setup, testconstants.IntermediateSubjectKeyID) - require.Equal(t, 0, len(allApprovedCertificates)) - allApprovedCertificates, _ = queryAllApprovedCertificatesBySubjectKeyID(setup, testconstants.LeafSubjectKeyID) - require.Equal(t, 0, len(allApprovedCertificates)) - - // check that no proposed certificate revocations have been created - allProposedCertificateRevocations, _ := queryAllProposedCertificateRevocations(setup) - require.NoError(t, err) - require.Equal(t, 0, len(allProposedCertificateRevocations)) - - // check that no child certificate identifiers are now registered for root certificate - _, err = queryChildCertificates(setup, testconstants.RootSubject, testconstants.RootSubjectKeyID) - require.Error(t, err) - require.Equal(t, codes.NotFound, status.Code(err)) - - // check that no child certificate identifiers are registered for revoked intermediate certificate - _, err = queryChildCertificates(setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) - require.Error(t, err) - require.Equal(t, codes.NotFound, status.Code(err)) - - // check that no child certificate identifiers are registered for revoked leaf certificate - _, err = queryChildCertificates(setup, testconstants.LeafSubject, testconstants.LeafSubjectKeyID) - require.Error(t, err) - require.Equal(t, codes.NotFound, status.Code(err)) -} - func TestHandler_RejectX509RootCert_TwoRejectApprovalsAreNeeded(t *testing.T) { setup := Setup(t) diff --git a/x/pki/keeper/keeper.go b/x/pki/keeper/keeper.go index 51a61c4a2..f9bf084b3 100644 --- a/x/pki/keeper/keeper.go +++ b/x/pki/keeper/keeper.go @@ -50,3 +50,33 @@ func (k Keeper) CertificateApprovalsCount(ctx sdk.Context, authKeeper types.Dcla func (k Keeper) CertificateRejectApprovalsCount(ctx sdk.Context, authKeeper types.DclauthKeeper) int { return authKeeper.CountAccountsWithRole(ctx, authTypes.Trustee) - k.CertificateApprovalsCount(ctx, authKeeper) + 1 } + +func (k Keeper) EnsureCertificateOwnership(ctx sdk.Context, certificate *types.Certificate, signer string) error { + // get signer VID + signerAddr, err := sdk.AccAddressFromBech32(signer) + if err != nil { + return pkitypes.NewErrInvalidAddress(err) + } + + signerAccount, _ := k.dclauthKeeper.GetAccountO(ctx, signerAddr) + signerVid := signerAccount.VendorID + + // get owner VID + ownerAddr, err := sdk.AccAddressFromBech32(certificate.Owner) + if err != nil { + return pkitypes.NewErrInvalidAddress(err) + } + + ownerAccount, _ := k.dclauthKeeper.GetAccountO(ctx, ownerAddr) + ownerVid := ownerAccount.VendorID + + if ownerVid != 0 { + if signerVid != ownerVid { + return pkitypes.NewErrUnauthorizedCertVendor(certificate.Subject, certificate.SubjectKeyId, ownerVid) + } + } else if signer != certificate.Owner { + return pkitypes.NewErrUnauthorizedCertOwner(certificate.Subject, certificate.SubjectKeyId) + } + + return nil +} diff --git a/x/pki/keeper/msg_server_add_noc_x_509_root_cert.go b/x/pki/keeper/msg_server_add_noc_x_509_root_cert.go index dc8da51aa..f578f44ac 100644 --- a/x/pki/keeper/msg_server_add_noc_x_509_root_cert.go +++ b/x/pki/keeper/msg_server_add_noc_x_509_root_cert.go @@ -68,7 +68,7 @@ func (k msgServer) AddNocX509RootCert(goCtx context.Context, msg *types.MsgAddNo // signer VID must be same as VID of existing certificates if signerVid != existingCertificate.Vid { - return nil, pkitypes.NewErrExistingCertVidNotEqualAccountVid( + return nil, pkitypes.NewErrUnauthorizedCertVendor( x509Certificate.Subject, x509Certificate.SubjectKeyID, existingCertificate.Vid, diff --git a/x/pki/keeper/msg_server_add_x_509_cert.go b/x/pki/keeper/msg_server_add_x_509_cert.go index 873fb342f..b2529b613 100644 --- a/x/pki/keeper/msg_server_add_x_509_cert.go +++ b/x/pki/keeper/msg_server_add_x_509_cert.go @@ -21,10 +21,7 @@ func (k msgServer) AddX509Cert(goCtx context.Context, msg *types.MsgAddX509Cert) // fail if certificate is self-signed if x509Certificate.IsSelfSigned() { - return nil, pkitypes.NewErrInappropriateCertificateType( - "Inappropriate Certificate Type: Passed certificate is self-signed, " + - "so it cannot be added to the system as a non-root certificate. " + - "To propose adding a root certificate please use `PROPOSE_ADD_X509_ROOT_CERT` transaction.") + return nil, pkitypes.NewErrNonRootCertificateSelfSigned() } // check if certificate with Issuer/Serial Number combination already exists @@ -50,9 +47,8 @@ func (k msgServer) AddX509Cert(goCtx context.Context, msg *types.MsgAddX509Cert) return nil, pkitypes.NewErrProvidedNotNocCertButExistingNoc(x509Certificate.Subject, x509Certificate.SubjectKeyID) } - // signer must be same as owner of existing certificates - if msg.Signer != existingCertificate.Owner { - return nil, pkitypes.NewErrUnauthorizedCertOwner(x509Certificate.Subject, x509Certificate.SubjectKeyID) + if err = k.EnsureCertificateOwnership(ctx, existingCertificate, msg.Signer); err != nil { + return nil, err } } diff --git a/x/pki/keeper/msg_server_propose_add_x_509_root_cert.go b/x/pki/keeper/msg_server_propose_add_x_509_root_cert.go index c9a6038a3..c932c6fbb 100644 --- a/x/pki/keeper/msg_server_propose_add_x_509_root_cert.go +++ b/x/pki/keeper/msg_server_propose_add_x_509_root_cert.go @@ -73,7 +73,7 @@ func (k msgServer) ProposeAddX509RootCert(goCtx context.Context, msg *types.MsgP } // signer must be same as owner of existing certificates - if msg.Signer != existingCertificates.Certs[0].Owner { + if msg.Signer != existingCertificate.Owner { return nil, pkitypes.NewErrUnauthorizedCertOwner(x509Certificate.Subject, x509Certificate.SubjectKeyID) } } diff --git a/x/pki/keeper/msg_server_remove_x_509_cert.go b/x/pki/keeper/msg_server_remove_x_509_cert.go index 731b4c3e5..c36211154 100644 --- a/x/pki/keeper/msg_server_remove_x_509_cert.go +++ b/x/pki/keeper/msg_server_remove_x_509_cert.go @@ -14,7 +14,8 @@ func (k msgServer) RemoveX509Cert(goCtx context.Context, msg *types.MsgRemoveX50 aprCerts, foundApproved := k.GetApprovedCertificates(ctx, msg.Subject, msg.SubjectKeyId) revCerts, foundRevoked := k.GetRevokedCertificates(ctx, msg.Subject, msg.SubjectKeyId) - certificates := append(aprCerts.Certs, revCerts.Certs...) //nolint:gocritic + certificates := aprCerts.Certs + certificates = append(certificates, revCerts.Certs...) if len(certificates) == 0 { return nil, pkitypes.NewErrCertificateDoesNotExist(msg.Subject, msg.SubjectKeyId) } @@ -23,8 +24,8 @@ func (k msgServer) RemoveX509Cert(goCtx context.Context, msg *types.MsgRemoveX50 return nil, pkitypes.NewErrMessageRemoveRoot(msg.Subject, msg.SubjectKeyId) } - if msg.Signer != certificates[0].Owner { - return nil, pkitypes.NewErrMessageOnlyOwnerCanExecute("REVOKE_X509_CERT") + if err := k.EnsureCertificateOwnership(ctx, certificates[0], msg.Signer); err != nil { + return nil, err } certID := types.CertificateIdentifier{ diff --git a/x/pki/keeper/msg_server_revoke_x_509_cert.go b/x/pki/keeper/msg_server_revoke_x_509_cert.go index ccfbffb65..1e5dc0386 100644 --- a/x/pki/keeper/msg_server_revoke_x_509_cert.go +++ b/x/pki/keeper/msg_server_revoke_x_509_cert.go @@ -2,10 +2,8 @@ package keeper import ( "context" - "fmt" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" pkitypes "github.com/zigbee-alliance/distributed-compliance-ledger/types/pki" "github.com/zigbee-alliance/distributed-compliance-ledger/x/pki/types" ) @@ -13,48 +11,39 @@ import ( func (k msgServer) RevokeX509Cert(goCtx context.Context, msg *types.MsgRevokeX509Cert) (*types.MsgRevokeX509CertResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - certificates, found := k.GetApprovedCertificates(ctx, msg.Subject, msg.SubjectKeyId) - if !found { + certificates, _ := k.GetApprovedCertificates(ctx, msg.Subject, msg.SubjectKeyId) + if len(certificates.Certs) == 0 { return nil, pkitypes.NewErrCertificateDoesNotExist(msg.Subject, msg.SubjectKeyId) } if certificates.Certs[0].IsRoot { - return nil, pkitypes.NewErrInappropriateCertificateType( - fmt.Sprintf("Inappropriate Certificate Type: Certificate with subject=%v and subjectKeyID=%v "+ - "is a root certificate. To propose revocation of a root certificate please use "+ - "`PROPOSE_REVOKE_X509_ROOT_CERT` transaction.", msg.Subject, msg.SubjectKeyId), - ) + return nil, pkitypes.NewErrMessageRemoveRoot(msg.Subject, msg.SubjectKeyId) } - if msg.Signer != certificates.Certs[0].Owner { - return nil, sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, - "Only owner can revoke certificate using `REVOKE_X509_CERT`", - ) + if err := k.EnsureCertificateOwnership(ctx, certificates.Certs[0], msg.Signer); err != nil { + return nil, err } certIdentifier := types.CertificateIdentifier{ Subject: msg.Subject, SubjectKeyId: msg.SubjectKeyId, } - var certBySerialNumber *types.Certificate if msg.SerialNumber != "" { - certBySerialNumber, found = findCertificate(msg.SerialNumber, &certificates.Certs) + certBySerialNumber, found := findCertificate(msg.SerialNumber, &certificates.Certs) if !found { return nil, pkitypes.NewErrCertificateBySerialNumberDoesNotExist(msg.Subject, msg.SubjectKeyId, msg.SerialNumber) } - } - if certBySerialNumber != nil { - k._removeAndRevokeX509CertBySerialNumber(ctx, certBySerialNumber, certIdentifier, certificates) + k._revokeX509CertBySerialNumber(ctx, certBySerialNumber, certIdentifier, certificates) } else { - k._removeAndRevokeX509Cert(ctx, certIdentifier, certificates) + k._revokeX509Cert(ctx, certIdentifier, certificates) } return &types.MsgRevokeX509CertResponse{}, nil } -func (k msgServer) _removeAndRevokeX509Cert(ctx sdk.Context, certID types.CertificateIdentifier, certificates types.ApprovedCertificates) { +func (k msgServer) _revokeX509Cert(ctx sdk.Context, certID types.CertificateIdentifier, certificates types.ApprovedCertificates) { // Revoke certificates with given subject/subjectKeyID k.AddRevokedCertificates(ctx, certificates) k.RemoveApprovedCertificates(ctx, certID.Subject, certID.SubjectKeyId) @@ -67,7 +56,7 @@ func (k msgServer) _removeAndRevokeX509Cert(ctx sdk.Context, certID types.Certif // remove from subject key ID -> certificates map k.RemoveApprovedCertificatesBySubjectKeyID(ctx, certID.Subject, certID.SubjectKeyId) } -func (k msgServer) _removeAndRevokeX509CertBySerialNumber(ctx sdk.Context, cert *types.Certificate, certID types.CertificateIdentifier, certificates types.ApprovedCertificates) { +func (k msgServer) _revokeX509CertBySerialNumber(ctx sdk.Context, cert *types.Certificate, certID types.CertificateIdentifier, certificates types.ApprovedCertificates) { k.AddRevokedCertificates(ctx, types.ApprovedCertificates{ Subject: cert.Subject, From 9b04d20cb2b627efe7fe55f7ad420f7450b9b3ae Mon Sep 17 00:00:00 2001 From: "aziz.karabashov" Date: Wed, 28 Feb 2024 13:09:50 +0500 Subject: [PATCH 02/14] Update tests to handle the removal of non-root certificates --- x/pki/handler_add_non_root_cert_test.go | 27 +- x/pki/handler_remove_non_root_cert_test.go | 444 +++++++++++++++++++++ x/pki/handler_revoke_non_root_cert_test.go | 33 +- x/pki/handler_test.go | 351 ---------------- 4 files changed, 473 insertions(+), 382 deletions(-) create mode 100644 x/pki/handler_remove_non_root_cert_test.go diff --git a/x/pki/handler_add_non_root_cert_test.go b/x/pki/handler_add_non_root_cert_test.go index fb632d1f2..155c56341 100644 --- a/x/pki/handler_add_non_root_cert_test.go +++ b/x/pki/handler_add_non_root_cert_test.go @@ -106,7 +106,7 @@ func TestHandler_AddX509Cert_ForRootCertificate(t *testing.T) { addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.RootCertPem) _, err := setup.Handler(setup.Ctx, addX509Cert) require.Error(t, err) - require.True(t, pkitypes.ErrInappropriateCertificateType.Is(err)) + require.True(t, pkitypes.ErrNonRootCertificateSelfSigned.Is(err)) } func TestHandler_AddX509Cert_ForDuplicate(t *testing.T) { @@ -202,11 +202,11 @@ func TestHandler_AddX509Cert_ForDifferentSerialNumberDifferentSigner(t *testing. setup := Setup(t) // store root certificate - rootCertificate := rootCertificate(testconstants.Address1) + rootCertificate := rootCertificate(setup.Trustee1) setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCertificate) // store intermediate certificate with different serial number - intermediateCertificate := intermediateCertificate(testconstants.Address1) + intermediateCertificate := intermediateCertificate(setup.Trustee1) intermediateCertificate.SerialNumber = SerialNumber setup.Keeper.SetUniqueCertificate( setup.Ctx, @@ -215,7 +215,7 @@ func TestHandler_AddX509Cert_ForDifferentSerialNumberDifferentSigner(t *testing. setup.Keeper.AddApprovedCertificate(setup.Ctx, intermediateCertificate) // store intermediate certificate second time - addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) + addX509Cert := types.NewMsgAddX509Cert(setup.Trustee2.String(), testconstants.IntermediateCertPem) _, err := setup.Handler(setup.Ctx, addX509Cert) require.Error(t, err) require.True(t, sdkerrors.ErrUnauthorized.Is(err)) @@ -399,10 +399,11 @@ func TestHandler_AddX509Cert_EachChildCertRefersToTwoParentCerts(t *testing.T) { func TestHandler_AddX509Cert_ByNotOwner(t *testing.T) { setup := Setup(t) + // store root certificate rootCertificate := rootCertificate(setup.Trustee1) setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCertificate) - // add an intermidiate certificate from vendor + // Store an intermediate certificate with the first trustee as the owner intermediateCertificate := intermediateCertificate(setup.Trustee1) intermediateCertificate.SerialNumber = SerialNumber setup.Keeper.AddApprovedCertificate(setup.Ctx, intermediateCertificate) @@ -412,7 +413,7 @@ func TestHandler_AddX509Cert_ByNotOwner(t *testing.T) { uniqueCertificate(intermediateCertificate.Issuer, intermediateCertificate.SerialNumber), ) - // add an intermediate certificate with the same subject and SKID from the same vendor but under a different account + // add an intermediate certificate with the same subject and SKID by second trustee addX509Cert := types.NewMsgAddX509Cert(setup.Trustee2.String(), testconstants.IntermediateCertPem) _, err := setup.Handler(setup.Ctx, addX509Cert) require.Error(t, err) @@ -422,13 +423,15 @@ func TestHandler_AddX509Cert_ByNotOwner(t *testing.T) { func TestHandler_AddX509Cert_ByNotOwnerButSameVendor(t *testing.T) { setup := Setup(t) + // store root certificate rootCertificate := rootCertificate(setup.Trustee1) setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCertificate) + // add first vendor account with VID = 1 vendorAccAddress1 := GenerateAccAddress() setup.AddAccount(vendorAccAddress1, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.Vid) - // add an intermidiate certificate from vendor + // Store an intermediate certificate with the first vendor account as the owner intermediateCertificate := intermediateCertificate(vendorAccAddress1) intermediateCertificate.SerialNumber = SerialNumber setup.Keeper.AddApprovedCertificate(setup.Ctx, intermediateCertificate) @@ -438,10 +441,11 @@ func TestHandler_AddX509Cert_ByNotOwnerButSameVendor(t *testing.T) { uniqueCertificate(intermediateCertificate.Issuer, intermediateCertificate.SerialNumber), ) + // add second vendor account with VID = 1 vendorAccAddress2 := GenerateAccAddress() setup.AddAccount(vendorAccAddress2, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.Vid) - // add an intermediate certificate with the same subject and SKID from the same vendor but under a different account + // add an intermediate certificate with the same subject and SKID by second vendor account addX509Cert := types.NewMsgAddX509Cert(vendorAccAddress2.String(), testconstants.IntermediateCertPem) _, err := setup.Handler(setup.Ctx, addX509Cert) require.NoError(t, err) @@ -450,13 +454,15 @@ func TestHandler_AddX509Cert_ByNotOwnerButSameVendor(t *testing.T) { func TestHandler_AddX509Cert_ByNotOwnerAndOtherVendor(t *testing.T) { setup := Setup(t) + // store root certificate rootCertificate := rootCertificate(setup.Trustee1) setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCertificate) + // add first vendor account with VID = 1 vendorAccAddress1 := GenerateAccAddress() setup.AddAccount(vendorAccAddress1, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.Vid) - // add an intermidiate certificate from vendor + // Store an intermediate certificate with the first vendor account as the owner intermediateCertificate := intermediateCertificate(vendorAccAddress1) intermediateCertificate.SerialNumber = SerialNumber setup.Keeper.AddApprovedCertificate(setup.Ctx, intermediateCertificate) @@ -466,10 +472,11 @@ func TestHandler_AddX509Cert_ByNotOwnerAndOtherVendor(t *testing.T) { uniqueCertificate(intermediateCertificate.Issuer, intermediateCertificate.SerialNumber), ) + // add seconf vendor account with VID = 1000 vendorAccAddress2 := GenerateAccAddress() setup.AddAccount(vendorAccAddress2, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.VendorID1) - // add an intermediate certificate with the same subject and SKID from the same vendor but under a different account + // add an intermediate certificate with the same subject and SKID by second vendor account addX509Cert := types.NewMsgAddX509Cert(vendorAccAddress2.String(), testconstants.IntermediateCertPem) _, err := setup.Handler(setup.Ctx, addX509Cert) require.Error(t, err) diff --git a/x/pki/handler_remove_non_root_cert_test.go b/x/pki/handler_remove_non_root_cert_test.go new file mode 100644 index 000000000..cca6791ad --- /dev/null +++ b/x/pki/handler_remove_non_root_cert_test.go @@ -0,0 +1,444 @@ +package pki + +import ( + "testing" + + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/stretchr/testify/require" + testconstants "github.com/zigbee-alliance/distributed-compliance-ledger/integration_tests/constants" + pkitypes "github.com/zigbee-alliance/distributed-compliance-ledger/types/pki" + dclauthtypes "github.com/zigbee-alliance/distributed-compliance-ledger/x/dclauth/types" + "github.com/zigbee-alliance/distributed-compliance-ledger/x/pki/types" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +func TestHandler_RemoveX509Cert_BySerialNumber(t *testing.T) { + setup := Setup(t) + // propose and approve x509 root certificate + rootCertOptions := &rootCertOptions{ + pemCert: testconstants.RootCertWithSameSubjectAndSKID1, + subject: testconstants.RootCertWithSameSubjectAndSKIDSubject, + subjectKeyID: testconstants.RootCertWithSameSubjectAndSKIDSubjectKeyID, + info: testconstants.Info, + vid: 65521, + } + proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOptions) + + // Add two intermediate certificates again + addIntermediateX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateWithSameSubjectAndSKID1) + _, err := setup.Handler(setup.Ctx, addIntermediateX509Cert) + require.NoError(t, err) + addIntermediateX509Cert = types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateWithSameSubjectAndSKID2) + _, err = setup.Handler(setup.Ctx, addIntermediateX509Cert) + require.NoError(t, err) + + // Add a leaf certificate + addLeafX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.LeafCertWithSameSubjectAndSKID) + _, err = setup.Handler(setup.Ctx, addLeafX509Cert) + require.NoError(t, err) + + intermediateCerts, _ := queryApprovedCertificates(setup, testconstants.IntermediateCertWithSameSubjectAndSKIDSubject, testconstants.IntermediateCertWithSameSubjectAndSKIDSubjectKeyID) + require.Equal(t, 2, len(intermediateCerts.Certs)) + require.Equal(t, testconstants.IntermediateCertWithSameSubjectAndSKIDSubject, intermediateCerts.Certs[0].Subject) + require.Equal(t, testconstants.IntermediateCertWithSameSubjectAndSKIDSubjectKeyID, intermediateCerts.Certs[0].SubjectKeyId) + + // remove intermediate certificate by serial number + removeX509Cert := types.NewMsgRemoveX509Cert( + setup.Trustee1.String(), + testconstants.IntermediateCertWithSameSubjectAndSKIDSubject, + testconstants.IntermediateCertWithSameSubjectAndSKIDSubjectKeyID, + testconstants.IntermediateCertWithSameSubjectAndSKID1SerialNumber, + ) + _, err = setup.Handler(setup.Ctx, removeX509Cert) + require.NoError(t, err) + + // check that only root, intermediate(with serial number 3) and leaf certificates exists + allCerts, _ := queryAllApprovedCertificates(setup) + require.Equal(t, 3, len(allCerts)) + require.Equal(t, 3, len(allCerts[0].Certs)+len(allCerts[1].Certs)+len(allCerts[2].Certs)) + leafCerts, _ := queryApprovedCertificates(setup, testconstants.LeafCertWithSameSubjectAndSKIDSubject, testconstants.LeafCertWithSameSubjectAndSKIDSubjectKeyID) + require.Equal(t, 1, len(leafCerts.Certs)) + + intermediateCerts, _ = queryApprovedCertificates(setup, testconstants.IntermediateCertWithSameSubjectAndSKIDSubject, testconstants.IntermediateCertWithSameSubjectAndSKIDSubjectKeyID) + require.Equal(t, 1, len(intermediateCerts.Certs)) + require.Equal(t, testconstants.IntermediateCertWithSameSubjectAndSKID2SerialNumber, intermediateCerts.Certs[0].SerialNumber) + + // remove intermediate certificate by serial number and check that leaf cert is not removed + removeX509Cert = types.NewMsgRemoveX509Cert( + setup.Trustee1.String(), + testconstants.IntermediateCertWithSameSubjectAndSKIDSubject, + testconstants.IntermediateCertWithSameSubjectAndSKIDSubjectKeyID, + testconstants.IntermediateCertWithSameSubjectAndSKID2SerialNumber, + ) + _, err = setup.Handler(setup.Ctx, removeX509Cert) + require.NoError(t, err) + + allCerts, _ = queryAllApprovedCertificates(setup) + require.Equal(t, 2, len(allCerts)) + require.Equal(t, 2, len(allCerts[0].Certs)+len(allCerts[1].Certs)) + + _, err = queryApprovedCertificates(setup, testconstants.IntermediateCertWithSameSubjectAndSKIDSubject, testconstants.IntermediateCertWithSameSubjectAndSKIDSubjectKeyID) + require.Equal(t, codes.NotFound, status.Code(err)) + + // check that unique certificates does not exists + found := setup.Keeper.IsUniqueCertificatePresent(setup.Ctx, testconstants.RootCertWithSameSubjectAndSKIDSubject, testconstants.IntermediateCertWithSameSubjectAndSKID1SerialNumber) + require.Equal(t, false, found) + found = setup.Keeper.IsUniqueCertificatePresent(setup.Ctx, testconstants.RootCertWithSameSubjectAndSKIDSubject, testconstants.IntermediateCertWithSameSubjectAndSKID2SerialNumber) + require.Equal(t, false, found) + + leafCerts, _ = queryApprovedCertificates(setup, testconstants.LeafCertWithSameSubjectAndSKIDSubject, testconstants.LeafCertWithSameSubjectAndSKIDSubjectKeyID) + require.Equal(t, 1, len(leafCerts.Certs)) +} + +func TestHandler_RemoveX509Cert_RevokedAndApprovedCertificate(t *testing.T) { + setup := Setup(t) + // propose and approve x509 root certificate + rootCertOptions := &rootCertOptions{ + pemCert: testconstants.RootCertWithSameSubjectAndSKID1, + subject: testconstants.RootCertWithSameSubjectAndSKIDSubject, + subjectKeyID: testconstants.RootCertWithSameSubjectAndSKIDSubjectKeyID, + info: testconstants.Info, + vid: 65521, + } + proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOptions) + + // Add an intermediate certificate + addIntermediateX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateWithSameSubjectAndSKID1) + _, err := setup.Handler(setup.Ctx, addIntermediateX509Cert) + require.NoError(t, err) + + // get certificates for further comparison + allCerts := setup.Keeper.GetAllApprovedCertificates(setup.Ctx) + require.NotNil(t, allCerts) + require.Equal(t, 2, len(allCerts)) + require.Equal(t, 2, len(allCerts[0].Certs)+len(allCerts[1].Certs)) + + // revoke an intermediate certificate + revokeX509Cert := types.NewMsgRemoveX509Cert( + setup.Trustee1.String(), + testconstants.IntermediateCertWithSameSubjectAndSKIDSubject, + testconstants.IntermediateCertWithSameSubjectAndSKIDSubjectKeyID, + testconstants.IntermediateCertWithSameSubjectAndSKID1SerialNumber, + ) + _, err = setup.Handler(setup.Ctx, revokeX509Cert) + require.NoError(t, err) + + // Add an intermediate certificate with new serial number + addIntermediateX509Cert = types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateWithSameSubjectAndSKID2) + _, err = setup.Handler(setup.Ctx, addIntermediateX509Cert) + require.NoError(t, err) + + intermediateCerts, _ := queryApprovedCertificates(setup, testconstants.IntermediateCertWithSameSubjectAndSKIDSubject, testconstants.IntermediateCertWithSameSubjectAndSKIDSubjectKeyID) + require.Equal(t, 1, len(intermediateCerts.Certs)) + require.Equal(t, testconstants.IntermediateCertWithSameSubjectAndSKIDSubject, intermediateCerts.Certs[0].Subject) + require.Equal(t, testconstants.IntermediateCertWithSameSubjectAndSKIDSubjectKeyID, intermediateCerts.Certs[0].SubjectKeyId) + require.Equal(t, testconstants.IntermediateCertWithSameSubjectAndSKID2SerialNumber, intermediateCerts.Certs[0].SerialNumber) + + // remove an intermediate certificate + removeX509Cert := types.NewMsgRemoveX509Cert( + setup.Trustee1.String(), + testconstants.IntermediateCertWithSameSubjectAndSKIDSubject, + testconstants.IntermediateCertWithSameSubjectAndSKIDSubjectKeyID, + testconstants.IntermediateCertWithSameSubjectAndSKID2SerialNumber, + ) + _, err = setup.Handler(setup.Ctx, removeX509Cert) + require.NoError(t, err) + + // check that only root and leaf certificates exists + allCerts, _ = queryAllApprovedCertificates(setup) + require.Equal(t, 1, len(allCerts)) + require.Equal(t, true, allCerts[0].Certs[0].IsRoot) + _, err = queryApprovedCertificates(setup, testconstants.IntermediateCertWithSameSubjectAndSKIDSubject, testconstants.IntermediateCertWithSameSubjectAndSKIDSubjectKeyID) + require.Equal(t, codes.NotFound, status.Code(err)) + _, err = queryRevokedCertificates(setup, testconstants.IntermediateCertWithSameSubjectAndSKIDSubject, testconstants.IntermediateCertWithSameSubjectAndSKIDSubjectKeyID) + require.Equal(t, codes.NotFound, status.Code(err)) + + // check that unique certificates does not exists + found := setup.Keeper.IsUniqueCertificatePresent(setup.Ctx, testconstants.RootCertWithSameSubjectAndSKIDSubject, testconstants.IntermediateCertWithSameSubjectAndSKID1SerialNumber) + require.Equal(t, false, found) + found = setup.Keeper.IsUniqueCertificatePresent(setup.Ctx, testconstants.RootCertWithSameSubjectAndSKIDSubject, testconstants.IntermediateCertWithSameSubjectAndSKID2SerialNumber) + require.Equal(t, false, found) +} + +func TestHandler_RemoveX509Cert_RevokedCertificate(t *testing.T) { + setup := Setup(t) + // propose and approve x509 root certificate + rootCertOptions := &rootCertOptions{ + pemCert: testconstants.RootCertPem, + subject: testconstants.RootSubject, + subjectKeyID: testconstants.RootSubjectKeyID, + info: testconstants.Info, + vid: 65521, + } + proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOptions) + + // Add two intermediate certificates again + addIntermediateX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) + _, err := setup.Handler(setup.Ctx, addIntermediateX509Cert) + require.NoError(t, err) + + intermediateCerts, _ := queryApprovedCertificates(setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) + require.Equal(t, 1, len(intermediateCerts.Certs)) + require.Equal(t, testconstants.IntermediateSubject, intermediateCerts.Certs[0].Subject) + require.Equal(t, testconstants.IntermediateSubjectKeyID, intermediateCerts.Certs[0].SubjectKeyId) + + // revoke intermediate certificate by serial number + revokeX509Cert := types.NewMsgRevokeX509Cert( + setup.Trustee1.String(), + testconstants.IntermediateSubject, + testconstants.IntermediateSubjectKeyID, + testconstants.IntermediateSerialNumber, + testconstants.Info, + ) + _, err = setup.Handler(setup.Ctx, revokeX509Cert) + require.NoError(t, err) + + _, err = queryApprovedCertificates(setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) + require.Equal(t, codes.NotFound, status.Code(err)) + + revokedCerts, _ := queryRevokedCertificates(setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) + require.Equal(t, 1, len(revokedCerts.Certs)) + require.Equal(t, testconstants.IntermediateSubject, revokedCerts.Certs[0].Subject) + require.Equal(t, testconstants.IntermediateSubjectKeyID, revokedCerts.Certs[0].SubjectKeyId) + + // remove intermediate certificate by serial number + removeX509Cert := types.NewMsgRemoveX509Cert( + setup.Trustee1.String(), + testconstants.IntermediateSubject, + testconstants.IntermediateSubjectKeyID, + testconstants.IntermediateSerialNumber, + ) + _, err = setup.Handler(setup.Ctx, removeX509Cert) + require.NoError(t, err) + + allCerts, _ := queryAllApprovedCertificates(setup) + require.Equal(t, 1, len(allCerts)) + require.Equal(t, true, allCerts[0].Certs[0].IsRoot) + + _, err = queryApprovedCertificates(setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) + require.Equal(t, codes.NotFound, status.Code(err)) + _, err = queryRevokedCertificates(setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) + require.Equal(t, codes.NotFound, status.Code(err)) + + // check that unique certificate does not exists + found := setup.Keeper.IsUniqueCertificatePresent(setup.Ctx, testconstants.IntermediateIssuer, testconstants.IntermediateSerialNumber) + require.Equal(t, false, found) +} + +func TestHandler_RemoveX509Cert_CertificateDoesNotExist(t *testing.T) { + setup := Setup(t) + + removeX509Cert := types.NewMsgRemoveX509Cert( + setup.Trustee1.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, testconstants.IntermediateSerialNumber) + _, err := setup.Handler(setup.Ctx, removeX509Cert) + require.Error(t, err) + require.True(t, pkitypes.ErrCertificateDoesNotExist.Is(err)) +} + +func TestHandler_RemoveX509Cert_EmptyCertificatesList(t *testing.T) { + setup := Setup(t) + + rootCertificate := rootCertificate(setup.Trustee1) + setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCertificate) + + setup.Keeper.SetApprovedCertificates( + setup.Ctx, + types.ApprovedCertificates{ + Subject: testconstants.IntermediateSubject, + SubjectKeyId: testconstants.IntermediateSubjectKeyID, + }, + ) + + removeX509Cert := types.NewMsgRemoveX509Cert( + setup.Trustee1.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, "") + _, err := setup.Handler(setup.Ctx, removeX509Cert) + require.Error(t, err) + require.True(t, pkitypes.ErrCertificateDoesNotExist.Is(err)) +} + +func TestHandler_RemoveX509Cert_ByNotOwner(t *testing.T) { + setup := Setup(t) + + rootCertificate := rootCertificate(setup.Trustee1) + setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCertificate) + + addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) + _, err := setup.Handler(setup.Ctx, addX509Cert) + require.NoError(t, err) + + anotherTrustee := GenerateAccAddress() + setup.AddAccount(anotherTrustee, []dclauthtypes.AccountRole{dclauthtypes.Trustee}, 1) + + removeX509Cert := types.NewMsgRemoveX509Cert( + anotherTrustee.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, "") + _, err = setup.Handler(setup.Ctx, removeX509Cert) + require.Error(t, err) + require.True(t, sdkerrors.ErrUnauthorized.Is(err)) +} + +func TestHandler_RemoveX509Cert_ByNotOwnerButSameVendor(t *testing.T) { + setup := Setup(t) + + // store root certificate + rootCertificate := rootCertificate(setup.Trustee1) + setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCertificate) + + // add first vendor account with VID = 1 + vendorAccAddress1 := GenerateAccAddress() + setup.AddAccount(vendorAccAddress1, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.Vid) + + // add x509 certificate by fist vendor account + addX509Cert := types.NewMsgAddX509Cert(vendorAccAddress1.String(), testconstants.IntermediateCertPem) + _, err := setup.Handler(setup.Ctx, addX509Cert) + require.NoError(t, err) + + // add second vendor account with VID = 1 + vendorAccAddress2 := GenerateAccAddress() + setup.AddAccount(vendorAccAddress2, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.Vid) + + // remove x509 certificate by second vendor account + removeX509Cert := types.NewMsgRemoveX509Cert( + vendorAccAddress2.String(), + testconstants.IntermediateSubject, + testconstants.IntermediateSubjectKeyID, + testconstants.IntermediateSerialNumber, + ) + _, err = setup.Handler(setup.Ctx, removeX509Cert) + require.NoError(t, err) + + // check that certificate removed from 'approved certificates' list + _, err = queryApprovedCertificates(setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) + require.Error(t, err) + require.Equal(t, codes.NotFound, status.Code(err)) + + // check that certificate removed from 'approved certificates by subject' list + _, err = queryApprovedCertificatesBySubject(setup, testconstants.IntermediateSubject) + require.Error(t, err) + require.Equal(t, codes.NotFound, status.Code(err)) + + // check that certificate removed from 'approved certificates by SKID' list + approvedCerts, err := queryAllApprovedCertificatesBySubjectKeyID(setup, testconstants.IntermediateSubjectKeyID) + require.NoError(t, err) + require.Equal(t, 0, len(approvedCerts)) + + // check that unique certificate key is not registered + require.False(t, setup.Keeper.IsUniqueCertificatePresent(setup.Ctx, + testconstants.IntermediateIssuer, testconstants.IntermediateSerialNumber)) +} + +func TestHandler_RemoveX509Cert_ByNotOwnerAndOtherVendor(t *testing.T) { + setup := Setup(t) + + // store root certificate + rootCertificate := rootCertificate(setup.Trustee1) + setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCertificate) + + // add fist vendor account with VID = 1 + vendorAccAddress1 := GenerateAccAddress() + setup.AddAccount(vendorAccAddress1, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.Vid) + + // add x509 certificate by `setup.Trustee` + addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) + _, err := setup.Handler(setup.Ctx, addX509Cert) + require.NoError(t, err) + + // add scond vendor account with VID = 1000 + vendorAccAddress2 := GenerateAccAddress() + setup.AddAccount(vendorAccAddress2, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.VendorID1) + + // revoke x509 certificate by second vendor account + removeX509Cert := types.NewMsgRemoveX509Cert( + vendorAccAddress2.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, testconstants.IntermediateSerialNumber) + _, err = setup.Handler(setup.Ctx, removeX509Cert) + require.Error(t, err) + require.True(t, sdkerrors.ErrUnauthorized.Is(err)) +} + +func TestHandler_RemoveX509Cert_ForRootCertificate(t *testing.T) { + setup := Setup(t) + + rootCertOptions := createTestRootCertOptions() + proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOptions) + + removeX509Cert := types.NewMsgRemoveX509Cert( + setup.Trustee1.String(), testconstants.RootSubject, testconstants.RootSubjectKeyID, testconstants.RootSerialNumber) + _, err := setup.Handler(setup.Ctx, removeX509Cert) + require.Error(t, err) + require.True(t, pkitypes.ErrInappropriateCertificateType.Is(err)) +} + +func TestHandler_RemoveX509Cert_InvalidSerialNumber(t *testing.T) { + setup := Setup(t) + + rootCertOptions := createTestRootCertOptions() + proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOptions) + + addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) + _, err := setup.Handler(setup.Ctx, addX509Cert) + require.NoError(t, err) + + removeX509Cert := types.NewMsgRemoveX509Cert( + setup.Trustee1.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, "invalid") + _, err = setup.Handler(setup.Ctx, removeX509Cert) + require.Error(t, err) + require.True(t, pkitypes.ErrCertificateDoesNotExist.Is(err)) +} + +func TestHandler_RemoveX509Cert_BySubjectAndSKID(t *testing.T) { + setup := Setup(t) + // propose and approve x509 root certificate + rootCertOptions := &rootCertOptions{ + pemCert: testconstants.RootCertWithSameSubjectAndSKID1, + subject: testconstants.RootCertWithSameSubjectAndSKIDSubject, + subjectKeyID: testconstants.RootCertWithSameSubjectAndSKIDSubjectKeyID, + info: testconstants.Info, + vid: 65521, + } + proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOptions) + + // Add two intermediate certificates + addIntermediateX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateWithSameSubjectAndSKID1) + _, err := setup.Handler(setup.Ctx, addIntermediateX509Cert) + require.NoError(t, err) + addIntermediateX509Cert = types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateWithSameSubjectAndSKID2) + _, err = setup.Handler(setup.Ctx, addIntermediateX509Cert) + require.NoError(t, err) + + // Add a leaf certificate + addLeafX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.LeafCertWithSameSubjectAndSKID) + _, err = setup.Handler(setup.Ctx, addLeafX509Cert) + require.NoError(t, err) + + // get certificates for further comparison + allCerts := setup.Keeper.GetAllApprovedCertificates(setup.Ctx) + require.NotNil(t, allCerts) + require.Equal(t, 3, len(allCerts)) + require.Equal(t, 4, len(allCerts[0].Certs)+len(allCerts[1].Certs)+len(allCerts[2].Certs)) + + // remove all intermediate certificates but leave leaf certificate + removeX509Cert := types.NewMsgRemoveX509Cert( + setup.Trustee1.String(), + testconstants.IntermediateCertWithSameSubjectAndSKIDSubject, + testconstants.IntermediateCertWithSameSubjectAndSKIDSubjectKeyID, + "", + ) + _, err = setup.Handler(setup.Ctx, removeX509Cert) + require.NoError(t, err) + + // check that only root and leaf certificates exists + allCerts, _ = queryAllApprovedCertificates(setup) + require.Equal(t, 2, len(allCerts)) + require.Equal(t, 2, len(allCerts[0].Certs)+len(allCerts[1].Certs)) + _, err = queryApprovedCertificates(setup, testconstants.IntermediateCertWithSameSubjectAndSKIDSubject, testconstants.IntermediateCertWithSameSubjectAndSKIDSubjectKeyID) + require.Equal(t, codes.NotFound, status.Code(err)) + // check that unique certificates does not exists + found := setup.Keeper.IsUniqueCertificatePresent(setup.Ctx, testconstants.RootCertWithSameSubjectAndSKIDSubject, testconstants.IntermediateCertWithSameSubjectAndSKID1SerialNumber) + require.Equal(t, false, found) + found = setup.Keeper.IsUniqueCertificatePresent(setup.Ctx, testconstants.RootCertWithSameSubjectAndSKIDSubject, testconstants.IntermediateCertWithSameSubjectAndSKID2SerialNumber) + require.Equal(t, false, found) + + leafCerts, _ := queryApprovedCertificates(setup, testconstants.LeafCertWithSameSubjectAndSKIDSubject, testconstants.LeafCertWithSameSubjectAndSKIDSubjectKeyID) + require.Equal(t, 1, len(leafCerts.Certs)) + require.Equal(t, testconstants.LeafCertWithSameSubjectAndSKIDSerialNumber, leafCerts.Certs[0].SerialNumber) +} diff --git a/x/pki/handler_revoke_non_root_cert_test.go b/x/pki/handler_revoke_non_root_cert_test.go index b56a0d941..5edcc64e9 100644 --- a/x/pki/handler_revoke_non_root_cert_test.go +++ b/x/pki/handler_revoke_non_root_cert_test.go @@ -179,20 +179,20 @@ func TestHandler_RevokeX509Cert_ByNotOwnerButSameVendor(t *testing.T) { rootCertificate := rootCertificate(setup.Trustee1) setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCertificate) - // add first vendor's account + // add first vendor account with VID = 1 vendorAccAddress1 := GenerateAccAddress() setup.AddAccount(vendorAccAddress1, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.Vid) - // add x509 certificate by vendor` + // add x509 certificate by first vendor account addX509Cert := types.NewMsgAddX509Cert(vendorAccAddress1.String(), testconstants.IntermediateCertPem) _, err := setup.Handler(setup.Ctx, addX509Cert) require.NoError(t, err) - // add second vendor's account + // add second vendor account with VID = 1 vendorAccAddress2 := GenerateAccAddress() setup.AddAccount(vendorAccAddress2, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.Vid) - // revoke x509 certificate by another account + // revoke x509 certificate by second vendor account revokeX509Cert := types.NewMsgRevokeX509Cert( vendorAccAddress2.String(), testconstants.IntermediateSubject, @@ -203,8 +203,6 @@ func TestHandler_RevokeX509Cert_ByNotOwnerButSameVendor(t *testing.T) { _, err = setup.Handler(setup.Ctx, revokeX509Cert) require.NoError(t, err) - // check that intermediate cer - // check that intermediate certificate has been added to revoked list revokedCertificates, _ := queryRevokedCertificates(setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) require.Equal(t, testconstants.IntermediateSubject, revokedCertificates.Subject) @@ -212,26 +210,21 @@ func TestHandler_RevokeX509Cert_ByNotOwnerButSameVendor(t *testing.T) { require.Equal(t, 1, len(revokedCertificates.Certs)) require.Equal(t, intermediateCertificate(vendorAccAddress1), *revokedCertificates.Certs[0]) - // check that revoked certificate remover from approved certificates list + // check that revoked certificate removed from approved certificates list _, err = queryApprovedCertificates(setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) require.Error(t, err) require.Equal(t, codes.NotFound, status.Code(err)) - // check that revoked certificate removed from approved certificates by subject list + // check that revoked certificate removed from 'approved certificates' by subject list _, err = queryApprovedCertificatesBySubject(setup, testconstants.IntermediateSubject) require.Error(t, err) require.Equal(t, codes.NotFound, status.Code(err)) - // check that revoked certificate removed from approved certificates by SKID list + // check that revoked certificate removed from 'approved certificates' by SKID list approvedCerts, err := queryAllApprovedCertificatesBySubjectKeyID(setup, testconstants.IntermediateSubjectKeyID) require.NoError(t, err) require.Equal(t, 0, len(approvedCerts)) - // check that child certificate identifiers list of issuer do not exist anymore - _, err = queryChildCertificates(setup, testconstants.IntermediateIssuer, testconstants.IntermediateAuthorityKeyID) - require.Error(t, err) - require.Equal(t, codes.NotFound, status.Code(err)) - // check that unique certificate key stays registered require.True(t, setup.Keeper.IsUniqueCertificatePresent(setup.Ctx, testconstants.IntermediateIssuer, testconstants.IntermediateSerialNumber)) @@ -244,24 +237,22 @@ func TestHandler_RevokeX509Cert_ByNotOwnerAndOtherVendor(t *testing.T) { rootCertificate := rootCertificate(setup.Trustee1) setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCertificate) + // add first vendor account with VID = 1 vendorAccAddress1 := GenerateAccAddress() setup.AddAccount(vendorAccAddress1, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.Vid) - // add x509 certificate by `setup.Trustee` + // add x509 certificate by first vendor account addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) _, err := setup.Handler(setup.Ctx, addX509Cert) require.NoError(t, err) - // store another account - anotherTrustee := GenerateAccAddress() - setup.AddAccount(anotherTrustee, []dclauthtypes.AccountRole{dclauthtypes.Trustee}, 1) - + // add second vendor account with VID = 1000 vendorAccAddress2 := GenerateAccAddress() setup.AddAccount(vendorAccAddress2, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.Vid) - // revoke x509 certificate by another account + // revoke x509 certificate by second vendor account revokeX509Cert := types.NewMsgRevokeX509Cert( - anotherTrustee.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, testconstants.IntermediateSerialNumber, testconstants.Info) + vendorAccAddress2.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, testconstants.IntermediateSerialNumber, testconstants.Info) _, err = setup.Handler(setup.Ctx, revokeX509Cert) require.Error(t, err) require.True(t, sdkerrors.ErrUnauthorized.Is(err)) diff --git a/x/pki/handler_test.go b/x/pki/handler_test.go index d3524c498..1371eb6aa 100644 --- a/x/pki/handler_test.go +++ b/x/pki/handler_test.go @@ -1199,357 +1199,6 @@ func TestHandler_ApproveRevokeX509RootCert_ForTree(t *testing.T) { require.Nil(t, leafCertChildren) } -func TestHandler_RemoveX509Cert_BySubjectAndSKID(t *testing.T) { - setup := Setup(t) - // propose and approve x509 root certificate - rootCertOptions := &rootCertOptions{ - pemCert: testconstants.RootCertWithSameSubjectAndSKID1, - subject: testconstants.RootCertWithSameSubjectAndSKIDSubject, - subjectKeyID: testconstants.RootCertWithSameSubjectAndSKIDSubjectKeyID, - info: testconstants.Info, - vid: 65521, - } - proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOptions) - - // Add two intermediate certificates - addIntermediateX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateWithSameSubjectAndSKID1) - _, err := setup.Handler(setup.Ctx, addIntermediateX509Cert) - require.NoError(t, err) - addIntermediateX509Cert = types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateWithSameSubjectAndSKID2) - _, err = setup.Handler(setup.Ctx, addIntermediateX509Cert) - require.NoError(t, err) - - // Add a leaf certificate - addLeafX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.LeafCertWithSameSubjectAndSKID) - _, err = setup.Handler(setup.Ctx, addLeafX509Cert) - require.NoError(t, err) - - // get certificates for further comparison - allCerts := setup.Keeper.GetAllApprovedCertificates(setup.Ctx) - require.NotNil(t, allCerts) - require.Equal(t, 3, len(allCerts)) - require.Equal(t, 4, len(allCerts[0].Certs)+len(allCerts[1].Certs)+len(allCerts[2].Certs)) - - // remove all intermediate certificates but leave leaf certificate - removeX509Cert := types.NewMsgRemoveX509Cert( - setup.Trustee1.String(), - testconstants.IntermediateCertWithSameSubjectAndSKIDSubject, - testconstants.IntermediateCertWithSameSubjectAndSKIDSubjectKeyID, - "", - ) - _, err = setup.Handler(setup.Ctx, removeX509Cert) - require.NoError(t, err) - - // check that only root and leaf certificates exists - allCerts, _ = queryAllApprovedCertificates(setup) - require.Equal(t, 2, len(allCerts)) - require.Equal(t, 2, len(allCerts[0].Certs)+len(allCerts[1].Certs)) - _, err = queryApprovedCertificates(setup, testconstants.IntermediateCertWithSameSubjectAndSKIDSubject, testconstants.IntermediateCertWithSameSubjectAndSKIDSubjectKeyID) - require.Equal(t, codes.NotFound, status.Code(err)) - // check that unique certificates does not exists - found := setup.Keeper.IsUniqueCertificatePresent(setup.Ctx, testconstants.RootCertWithSameSubjectAndSKIDSubject, testconstants.IntermediateCertWithSameSubjectAndSKID1SerialNumber) - require.Equal(t, false, found) - found = setup.Keeper.IsUniqueCertificatePresent(setup.Ctx, testconstants.RootCertWithSameSubjectAndSKIDSubject, testconstants.IntermediateCertWithSameSubjectAndSKID2SerialNumber) - require.Equal(t, false, found) - - leafCerts, _ := queryApprovedCertificates(setup, testconstants.LeafCertWithSameSubjectAndSKIDSubject, testconstants.LeafCertWithSameSubjectAndSKIDSubjectKeyID) - require.Equal(t, 1, len(leafCerts.Certs)) - require.Equal(t, testconstants.LeafCertWithSameSubjectAndSKIDSerialNumber, leafCerts.Certs[0].SerialNumber) -} - -func TestHandler_RemoveX509Cert_BySerialNumber(t *testing.T) { - setup := Setup(t) - // propose and approve x509 root certificate - rootCertOptions := &rootCertOptions{ - pemCert: testconstants.RootCertWithSameSubjectAndSKID1, - subject: testconstants.RootCertWithSameSubjectAndSKIDSubject, - subjectKeyID: testconstants.RootCertWithSameSubjectAndSKIDSubjectKeyID, - info: testconstants.Info, - vid: 65521, - } - proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOptions) - - // Add two intermediate certificates again - addIntermediateX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateWithSameSubjectAndSKID1) - _, err := setup.Handler(setup.Ctx, addIntermediateX509Cert) - require.NoError(t, err) - addIntermediateX509Cert = types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateWithSameSubjectAndSKID2) - _, err = setup.Handler(setup.Ctx, addIntermediateX509Cert) - require.NoError(t, err) - - // Add a leaf certificate - addLeafX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.LeafCertWithSameSubjectAndSKID) - _, err = setup.Handler(setup.Ctx, addLeafX509Cert) - require.NoError(t, err) - - intermediateCerts, _ := queryApprovedCertificates(setup, testconstants.IntermediateCertWithSameSubjectAndSKIDSubject, testconstants.IntermediateCertWithSameSubjectAndSKIDSubjectKeyID) - require.Equal(t, 2, len(intermediateCerts.Certs)) - require.Equal(t, testconstants.IntermediateCertWithSameSubjectAndSKIDSubject, intermediateCerts.Certs[0].Subject) - require.Equal(t, testconstants.IntermediateCertWithSameSubjectAndSKIDSubjectKeyID, intermediateCerts.Certs[0].SubjectKeyId) - - // remove intermediate certificate by serial number - removeX509Cert := types.NewMsgRemoveX509Cert( - setup.Trustee1.String(), - testconstants.IntermediateCertWithSameSubjectAndSKIDSubject, - testconstants.IntermediateCertWithSameSubjectAndSKIDSubjectKeyID, - testconstants.IntermediateCertWithSameSubjectAndSKID1SerialNumber, - ) - _, err = setup.Handler(setup.Ctx, removeX509Cert) - require.NoError(t, err) - - // check that only root, intermediate(with serial number 3) and leaf certificates exists - allCerts, _ := queryAllApprovedCertificates(setup) - require.Equal(t, 3, len(allCerts)) - require.Equal(t, 3, len(allCerts[0].Certs)+len(allCerts[1].Certs)+len(allCerts[2].Certs)) - leafCerts, _ := queryApprovedCertificates(setup, testconstants.LeafCertWithSameSubjectAndSKIDSubject, testconstants.LeafCertWithSameSubjectAndSKIDSubjectKeyID) - require.Equal(t, 1, len(leafCerts.Certs)) - - intermediateCerts, _ = queryApprovedCertificates(setup, testconstants.IntermediateCertWithSameSubjectAndSKIDSubject, testconstants.IntermediateCertWithSameSubjectAndSKIDSubjectKeyID) - require.Equal(t, 1, len(intermediateCerts.Certs)) - require.Equal(t, testconstants.IntermediateCertWithSameSubjectAndSKID2SerialNumber, intermediateCerts.Certs[0].SerialNumber) - - // remove intermediate certificate by serial number and check that leaf cert is not removed - removeX509Cert = types.NewMsgRemoveX509Cert( - setup.Trustee1.String(), - testconstants.IntermediateCertWithSameSubjectAndSKIDSubject, - testconstants.IntermediateCertWithSameSubjectAndSKIDSubjectKeyID, - testconstants.IntermediateCertWithSameSubjectAndSKID2SerialNumber, - ) - _, err = setup.Handler(setup.Ctx, removeX509Cert) - require.NoError(t, err) - - allCerts, _ = queryAllApprovedCertificates(setup) - require.Equal(t, 2, len(allCerts)) - require.Equal(t, 2, len(allCerts[0].Certs)+len(allCerts[1].Certs)) - - _, err = queryApprovedCertificates(setup, testconstants.IntermediateCertWithSameSubjectAndSKIDSubject, testconstants.IntermediateCertWithSameSubjectAndSKIDSubjectKeyID) - require.Equal(t, codes.NotFound, status.Code(err)) - - // check that unique certificates does not exists - found := setup.Keeper.IsUniqueCertificatePresent(setup.Ctx, testconstants.RootCertWithSameSubjectAndSKIDSubject, testconstants.IntermediateCertWithSameSubjectAndSKID1SerialNumber) - require.Equal(t, false, found) - found = setup.Keeper.IsUniqueCertificatePresent(setup.Ctx, testconstants.RootCertWithSameSubjectAndSKIDSubject, testconstants.IntermediateCertWithSameSubjectAndSKID2SerialNumber) - require.Equal(t, false, found) - - leafCerts, _ = queryApprovedCertificates(setup, testconstants.LeafCertWithSameSubjectAndSKIDSubject, testconstants.LeafCertWithSameSubjectAndSKIDSubjectKeyID) - require.Equal(t, 1, len(leafCerts.Certs)) -} - -func TestHandler_RemoveX509Cert_RevokedAndApprovedCertificate(t *testing.T) { - setup := Setup(t) - // propose and approve x509 root certificate - rootCertOptions := &rootCertOptions{ - pemCert: testconstants.RootCertWithSameSubjectAndSKID1, - subject: testconstants.RootCertWithSameSubjectAndSKIDSubject, - subjectKeyID: testconstants.RootCertWithSameSubjectAndSKIDSubjectKeyID, - info: testconstants.Info, - vid: 65521, - } - proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOptions) - - // Add an intermediate certificate - addIntermediateX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateWithSameSubjectAndSKID1) - _, err := setup.Handler(setup.Ctx, addIntermediateX509Cert) - require.NoError(t, err) - - // get certificates for further comparison - allCerts := setup.Keeper.GetAllApprovedCertificates(setup.Ctx) - require.NotNil(t, allCerts) - require.Equal(t, 2, len(allCerts)) - require.Equal(t, 2, len(allCerts[0].Certs)+len(allCerts[1].Certs)) - - // revoke an intermediate certificate - revokeX509Cert := types.NewMsgRemoveX509Cert( - setup.Trustee1.String(), - testconstants.IntermediateCertWithSameSubjectAndSKIDSubject, - testconstants.IntermediateCertWithSameSubjectAndSKIDSubjectKeyID, - testconstants.IntermediateCertWithSameSubjectAndSKID1SerialNumber, - ) - _, err = setup.Handler(setup.Ctx, revokeX509Cert) - require.NoError(t, err) - - // Add an intermediate certificate with new serial number - addIntermediateX509Cert = types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateWithSameSubjectAndSKID2) - _, err = setup.Handler(setup.Ctx, addIntermediateX509Cert) - require.NoError(t, err) - - intermediateCerts, _ := queryApprovedCertificates(setup, testconstants.IntermediateCertWithSameSubjectAndSKIDSubject, testconstants.IntermediateCertWithSameSubjectAndSKIDSubjectKeyID) - require.Equal(t, 1, len(intermediateCerts.Certs)) - require.Equal(t, testconstants.IntermediateCertWithSameSubjectAndSKIDSubject, intermediateCerts.Certs[0].Subject) - require.Equal(t, testconstants.IntermediateCertWithSameSubjectAndSKIDSubjectKeyID, intermediateCerts.Certs[0].SubjectKeyId) - require.Equal(t, testconstants.IntermediateCertWithSameSubjectAndSKID2SerialNumber, intermediateCerts.Certs[0].SerialNumber) - - // remove an intermediate certificate - removeX509Cert := types.NewMsgRemoveX509Cert( - setup.Trustee1.String(), - testconstants.IntermediateCertWithSameSubjectAndSKIDSubject, - testconstants.IntermediateCertWithSameSubjectAndSKIDSubjectKeyID, - testconstants.IntermediateCertWithSameSubjectAndSKID2SerialNumber, - ) - _, err = setup.Handler(setup.Ctx, removeX509Cert) - require.NoError(t, err) - - // check that only root and leaf certificates exists - allCerts, _ = queryAllApprovedCertificates(setup) - require.Equal(t, 1, len(allCerts)) - require.Equal(t, true, allCerts[0].Certs[0].IsRoot) - _, err = queryApprovedCertificates(setup, testconstants.IntermediateCertWithSameSubjectAndSKIDSubject, testconstants.IntermediateCertWithSameSubjectAndSKIDSubjectKeyID) - require.Equal(t, codes.NotFound, status.Code(err)) - _, err = queryRevokedCertificates(setup, testconstants.IntermediateCertWithSameSubjectAndSKIDSubject, testconstants.IntermediateCertWithSameSubjectAndSKIDSubjectKeyID) - require.Equal(t, codes.NotFound, status.Code(err)) - - // check that unique certificates does not exists - found := setup.Keeper.IsUniqueCertificatePresent(setup.Ctx, testconstants.RootCertWithSameSubjectAndSKIDSubject, testconstants.IntermediateCertWithSameSubjectAndSKID1SerialNumber) - require.Equal(t, false, found) - found = setup.Keeper.IsUniqueCertificatePresent(setup.Ctx, testconstants.RootCertWithSameSubjectAndSKIDSubject, testconstants.IntermediateCertWithSameSubjectAndSKID2SerialNumber) - require.Equal(t, false, found) -} - -func TestHandler_RemoveX509Cert_RevokedCertificate(t *testing.T) { - setup := Setup(t) - // propose and approve x509 root certificate - rootCertOptions := &rootCertOptions{ - pemCert: testconstants.RootCertPem, - subject: testconstants.RootSubject, - subjectKeyID: testconstants.RootSubjectKeyID, - info: testconstants.Info, - vid: 65521, - } - proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOptions) - - // Add two intermediate certificates again - addIntermediateX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) - _, err := setup.Handler(setup.Ctx, addIntermediateX509Cert) - require.NoError(t, err) - - intermediateCerts, _ := queryApprovedCertificates(setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) - require.Equal(t, 1, len(intermediateCerts.Certs)) - require.Equal(t, testconstants.IntermediateSubject, intermediateCerts.Certs[0].Subject) - require.Equal(t, testconstants.IntermediateSubjectKeyID, intermediateCerts.Certs[0].SubjectKeyId) - - // revoke intermediate certificate by serial number - revokeX509Cert := types.NewMsgRevokeX509Cert( - setup.Trustee1.String(), - testconstants.IntermediateSubject, - testconstants.IntermediateSubjectKeyID, - testconstants.IntermediateSerialNumber, - testconstants.Info, - ) - _, err = setup.Handler(setup.Ctx, revokeX509Cert) - require.NoError(t, err) - - _, err = queryApprovedCertificates(setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) - require.Equal(t, codes.NotFound, status.Code(err)) - - revokedCerts, _ := queryRevokedCertificates(setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) - require.Equal(t, 1, len(revokedCerts.Certs)) - require.Equal(t, testconstants.IntermediateSubject, revokedCerts.Certs[0].Subject) - require.Equal(t, testconstants.IntermediateSubjectKeyID, revokedCerts.Certs[0].SubjectKeyId) - - // remove intermediate certificate by serial number - removeX509Cert := types.NewMsgRemoveX509Cert( - setup.Trustee1.String(), - testconstants.IntermediateSubject, - testconstants.IntermediateSubjectKeyID, - testconstants.IntermediateSerialNumber, - ) - _, err = setup.Handler(setup.Ctx, removeX509Cert) - require.NoError(t, err) - - allCerts, _ := queryAllApprovedCertificates(setup) - require.Equal(t, 1, len(allCerts)) - require.Equal(t, true, allCerts[0].Certs[0].IsRoot) - - _, err = queryApprovedCertificates(setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) - require.Equal(t, codes.NotFound, status.Code(err)) - _, err = queryRevokedCertificates(setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) - require.Equal(t, codes.NotFound, status.Code(err)) - - // check that unique certificate does not exists - found := setup.Keeper.IsUniqueCertificatePresent(setup.Ctx, testconstants.IntermediateIssuer, testconstants.IntermediateSerialNumber) - require.Equal(t, false, found) -} - -func TestHandler_RemoveX509Cert_CertificateDoesNotExist(t *testing.T) { - setup := Setup(t) - - removeX509Cert := types.NewMsgRemoveX509Cert( - setup.Trustee1.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, testconstants.IntermediateSerialNumber) - _, err := setup.Handler(setup.Ctx, removeX509Cert) - require.Error(t, err) - require.True(t, pkitypes.ErrCertificateDoesNotExist.Is(err)) -} - -func TestHandler_RemoveX509Cert_EmptyCertificatesList(t *testing.T) { - setup := Setup(t) - - rootCertificate := rootCertificate(setup.Trustee1) - setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCertificate) - - setup.Keeper.SetApprovedCertificates( - setup.Ctx, - types.ApprovedCertificates{ - Subject: testconstants.IntermediateSubject, - SubjectKeyId: testconstants.IntermediateSubjectKeyID, - }, - ) - - removeX509Cert := types.NewMsgRemoveX509Cert( - setup.Trustee1.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, "") - _, err := setup.Handler(setup.Ctx, removeX509Cert) - require.Error(t, err) - require.True(t, pkitypes.ErrCertificateDoesNotExist.Is(err)) -} - -func TestHandler_RemoveX509Cert_ByNotOwner(t *testing.T) { - setup := Setup(t) - - rootCertificate := rootCertificate(setup.Trustee1) - setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCertificate) - - addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) - _, err := setup.Handler(setup.Ctx, addX509Cert) - require.NoError(t, err) - - anotherTrustee := GenerateAccAddress() - setup.AddAccount(anotherTrustee, []dclauthtypes.AccountRole{dclauthtypes.Trustee}, 1) - - removeX509Cert := types.NewMsgRemoveX509Cert( - anotherTrustee.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, "") - _, err = setup.Handler(setup.Ctx, removeX509Cert) - require.Error(t, err) - require.True(t, sdkerrors.ErrUnauthorized.Is(err)) -} - -func TestHandler_RemoveX509Cert_ForRootCertificate(t *testing.T) { - setup := Setup(t) - - rootCertOptions := createTestRootCertOptions() - proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOptions) - - removeX509Cert := types.NewMsgRemoveX509Cert( - setup.Trustee1.String(), testconstants.RootSubject, testconstants.RootSubjectKeyID, testconstants.RootSerialNumber) - _, err := setup.Handler(setup.Ctx, removeX509Cert) - require.Error(t, err) - require.True(t, pkitypes.ErrInappropriateCertificateType.Is(err)) -} - -func TestHandler_RemoveX509Cert_InvalidSerialNumber(t *testing.T) { - setup := Setup(t) - - rootCertOptions := createTestRootCertOptions() - proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOptions) - - addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) - _, err := setup.Handler(setup.Ctx, addX509Cert) - require.NoError(t, err) - - removeX509Cert := types.NewMsgRemoveX509Cert( - setup.Trustee1.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, "invalid") - _, err = setup.Handler(setup.Ctx, removeX509Cert) - require.Error(t, err) - require.True(t, pkitypes.ErrCertificateDoesNotExist.Is(err)) -} func TestHandler_RevokeX509RootCertsBySubjectKeyId(t *testing.T) { setup := Setup(t) From 52bf54b674330ade9a864220dcf84b3c3f8f2643 Mon Sep 17 00:00:00 2001 From: "aziz.karabashov" Date: Fri, 1 Mar 2024 10:54:48 +0500 Subject: [PATCH 03/14] Fix validations for the 'Add X.509 Certificate' transaction --- .../cli/pki-add-vendor-x509-certificates.sh | 82 +++- integration_tests/constants/constants.go | 8 +- integration_tests/grpc_rest/pki/helpers.go | 4 +- types/pki/errors.go | 21 +- x/pki/handler_add_non_root_cert_test.go | 453 ++++++++++++------ x/pki/handler_remove_non_root_cert_test.go | 1 + x/pki/handler_revoke_non_root_cert_test.go | 84 +++- x/pki/handler_test.go | 10 + x/pki/keeper/approved_certificates.go | 16 - x/pki/keeper/keeper.go | 10 +- x/pki/keeper/msg_server_add_x_509_cert.go | 100 ++-- x/pki/keeper/msg_server_remove_x_509_cert.go | 13 +- x/pki/keeper/msg_server_revoke_x_509_cert.go | 13 +- 13 files changed, 582 insertions(+), 233 deletions(-) diff --git a/integration_tests/cli/pki-add-vendor-x509-certificates.sh b/integration_tests/cli/pki-add-vendor-x509-certificates.sh index d7c12bb3f..3927a2751 100755 --- a/integration_tests/cli/pki-add-vendor-x509-certificates.sh +++ b/integration_tests/cli/pki-add-vendor-x509-certificates.sh @@ -5,13 +5,15 @@ root_cert_with_vid_65521_subject="MIGYMQswCQYDVQQGEwJVUzERMA8GA1UECAwITmV3IFlvcm root_cert_with_vid_65521_subject_key_id="CE:A8:92:66:EA:E0:80:BD:2B:B5:68:E4:0B:07:C4:FA:2C:34:6D:31" root_cert_with_vid_65521_path="integration_tests/constants/root_cert_with_vid" root_cert_with_vid_65521_vid=65521 -intermediate_cert_with_vid_subject="MIGuMQswCQYDVQQGEwJVUzERMA8GA1UECAwITmV3IFlvcmsxETAPBgNVBAcMCE5ldyBZb3JrMRgwFgYDVQQKDA9FeGFtcGxlIENvbXBhbnkxGTAXBgNVBAsMEFRlc3RpbmcgRGl2aXNpb24xGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTEUMBIGCisGAQQBgqJ8AgEMBEZGRjExFDASBgorBgEEAYKifAICDARGRkYx" -intermediate_cert_with_vid_subject_key_id="0E:8C:E8:C8:B8:AA:50:BC:25:85:56:B9:B1:9C:C2:C7:D9:C5:2F:17" + +intermediate_cert_with_vid_65521_subject="MIGuMQswCQYDVQQGEwJVUzERMA8GA1UECAwITmV3IFlvcmsxETAPBgNVBAcMCE5ldyBZb3JrMRgwFgYDVQQKDA9FeGFtcGxlIENvbXBhbnkxGTAXBgNVBAsMEFRlc3RpbmcgRGl2aXNpb24xGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTEUMBIGCisGAQQBgqJ8AgEMBEZGRjExFDASBgorBgEEAYKifAICDARGRkYx" +intermediate_cert_with_vid_65521_subject_key_id="0E:8C:E8:C8:B8:AA:50:BC:25:85:56:B9:B1:9C:C2:C7:D9:C5:2F:17" intermediate_cert_with_vid_65521_path="integration_tests/constants/intermediate_cert_with_vid_1" -intermediate_cert_with_vid_65522_path="integration_tests/constants/intermediate_cert_with_vid_2" intermediate_cert_with_vid_65521_serial_number="3" -intermediate_cert_with_vid_65522_serial_number="4" intermediate_cert_with_vid_65521_vid=65521 + +intermediate_cert_with_vid_65522_path="integration_tests/constants/intermediate_cert_with_vid_2" +intermediate_cert_with_vid_65522_serial_number="4" intermediate_cert_with_vid_65522_vid=65522 trustee_account="jack" @@ -41,8 +43,8 @@ result=$(dcld query pki all-x509-certs) echo $result | jq check_response "$result" "\"subject\": \"$root_cert_with_vid_65521_subject\"" check_response "$result" "\"subjectKeyId\": \"$root_cert_with_vid_65521_subject_key_id\"" -check_response "$result" "\"subject\": \"$intermediate_cert_with_vid_subject\"" -check_response "$result" "\"subjectKeyId\": \"$intermediate_cert_with_vid_subject_key_id\"" +check_response "$result" "\"subject\": \"$intermediate_cert_with_vid_65521_subject\"" +check_response "$result" "\"subjectKeyId\": \"$intermediate_cert_with_vid_65521_subject_key_id\"" check_response "$result" "\"serialNumber\": \"$intermediate_cert_with_vid_65521_serial_number\"" echo "Try to add an intermediate certificate with vid=$intermediate_cert_with_vid_65522_vid by $vendor_account_65521 with vid=$vendor_vid_65521" @@ -53,15 +55,16 @@ echo "Request all approved root certificates should not contain intermediate cer result=$(dcld query pki all-x509-certs) echo $result | jq check_response "$result" "\"subject\": \"$root_cert_with_vid_65521_subject\"" -check_response "$result" "\"subject\": \"$intermediate_cert_with_vid_subject\"" +check_response "$result" "\"subject\": \"$intermediate_cert_with_vid_65521_subject\"" check_response "$result" "\"subjectKeyId\": \"$root_cert_with_vid_65521_subject_key_id\"" -check_response "$result" "\"subjectKeyId\": \"$intermediate_cert_with_vid_subject_key_id\"" +check_response "$result" "\"subjectKeyId\": \"$intermediate_cert_with_vid_65521_subject_key_id\"" check_response "$result" "\"serialNumber\": \"$intermediate_cert_with_vid_65521_serial_number\"" response_does_not_contain "$result" "\"serialNumber\": \"$intermediate_cert_with_vid_65522_serial_number\"" root_cert_with_no_vid_path="integration_tests/constants/paa_cert_no_vid" root_cert_with_no_vid_subject="MBoxGDAWBgNVBAMMD01hdHRlciBUZXN0IFBBQQ==" root_cert_with_no_vid_subject_key_id="78:5C:E7:05:B8:6B:8F:4E:6F:C7:93:AA:60:CB:43:EA:69:68:82:D5" + intermediate_cert_with_vid_65522_path="integration_tests/constants/pai_cert_numeric_vid" intermediate_cert_with_vid_65522_subject="MDAxGDAWBgNVBAMMD01hdHRlciBUZXN0IFBBSTEUMBIGCisGAQQBgqJ8AgEMBEZGRjI=" intermediate_cert_with_vid_65522_subject_key_id="61:3D:D0:87:35:5E:F0:8B:AE:01:E4:C6:9A:8F:C7:3D:AC:8C:7D:FD" @@ -111,3 +114,66 @@ check_response "$result" "\"subjectKeyId\": \"$intermediate_cert_with_vid_65522_ check_response "$result" "\"serialNumber\": \"$intermediate_cert_with_vid_65522_serial_number\"" test_divider + +root_cert_subject="MIGCMQswCQYDVQQGEwJVUzERMA8GA1UECAwITmV3IFlvcmsxETAPBgNVBAcMCE5ldyBZb3JrMRgwFgYDVQQKDA9FeGFtcGxlIENvbXBhbnkxGTAXBgNVBAsMEFRlc3RpbmcgRGl2aXNpb24xGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbQ==" +root_cert_subject_key_id="33:5E:0C:07:44:F8:B5:9C:CD:55:01:9B:6D:71:23:83:6F:D0:D4:BE" +root_cert_path="integration_tests/constants/root_with_same_subject_and_skid_1" +root_cert_serial_number="1" + +intermediate_cert_subject="MEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQ=" +intermediate_cert_subject_key_id="2E:13:3B:44:52:2C:30:E9:EC:FB:45:FA:5D:E5:04:0A:C1:C6:E6:B9" +intermediate_cert_1_path="integration_tests/constants/intermediate_with_same_subject_and_skid_1" +intermediate_cert_1_serial_number="3" +intermediate_cert_2_path="integration_tests/constants/intermediate_with_same_subject_and_skid_2" +intermediate_cert_2_serial_number="4" + +echo "Propose and approve root certificate" +result=$(echo "$passphrase" | dcld tx pki propose-add-x509-root-cert --certificate="$root_cert_path" --vid "$vendor_vid_65521" --from $trustee_account --yes) +check_response "$result" "\"code\": 0" +result=$(echo "$passphrase" | dcld tx pki approve-add-x509-root-cert --subject="$root_cert_subject" --subject-key-id="$root_cert_subject_key_id" --from $second_trustee_account --yes) +check_response "$result" "\"code\": 0" + +echo "Add first intermediate certificate by $vendor_account_65521" +result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$intermediate_cert_1_path" --from $vendor_account_65521 --yes) +check_response "$result" "\"code\": 0" + +echo "Request all approved root certificates." +result=$(dcld query pki all-x509-certs) +echo $result | jq +check_response "$result" "\"subject\": \"$root_cert_subject\"" +check_response "$result" "\"subjectKeyId\": \"$root_cert_subject_key_id\"" +check_response "$result" "\"subject\": \"$intermediate_cert_subject\"" +check_response "$result" "\"subjectKeyId\": \"$intermediate_cert_subject_key_id\"" +check_response "$result" "\"serialNumber\": \"$intermediate_cert_1_serial_number\"" + +echo "Try add second intermediate certificate with same subject and SKID by $vendor_account_65523" +result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$intermediate_cert_2_path" --from $vendor_account_65523 --yes) +check_response "$result" "\"code\": 4" + +echo "Request all approved root certificates should not contain intermediate cert with serialNumber=$intermediate_cert_2_serial_number" +result=$(dcld query pki all-x509-certs) +echo $result | jq +check_response "$result" "\"subject\": \"$root_cert_subject\"" +check_response "$result" "\"subjectKeyId\": \"$root_cert_subject_key_id\"" +check_response "$result" "\"subject\": \"$intermediate_cert_subject\"" +check_response "$result" "\"subjectKeyId\": \"$intermediate_cert_subject_key_id\"" +check_response "$result" "\"serialNumber\": \"$intermediate_cert_1_serial_number\"" +response_does_not_contain "$result" "\"serialNumber\": \"$intermediate_cert_2_serial_number\"" + +second_vendor_account_65521=second_vendor_account_$vendor_vid_65521 +echo "Create Vendor account - $second_vendor_account_65521" +create_new_vendor_account $second_vendor_account_65521 $vendor_vid_65521 + +echo "Add second intermediate certificate with same subject and SKID by $second_vendor_account_65521" +result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$intermediate_cert_2_path" --from $vendor_account_65523 --yes) +check_response "$result" "\"code\": 4" + +echo "Request all approved root certificates should contain intermediate cert with serialNumber=$intermediate_cert_2_serial_number" +result=$(dcld query pki all-x509-certs) +echo $result | jq +check_response "$result" "\"subject\": \"$root_cert_subject\"" +check_response "$result" "\"subjectKeyId\": \"$root_cert_subject_key_id\"" +check_response "$result" "\"subject\": \"$intermediate_cert_subject\"" +check_response "$result" "\"subjectKeyId\": \"$intermediate_cert_subject_key_id\"" +check_response "$result" "\"serialNumber\": \"$intermediate_cert_1_serial_number\"" +check_response "$result" "\"serialNumber\": \"$intermediate_cert_2_serial_number\"" diff --git a/integration_tests/constants/constants.go b/integration_tests/constants/constants.go index b494f8c33..df67bac6c 100644 --- a/integration_tests/constants/constants.go +++ b/integration_tests/constants/constants.go @@ -655,10 +655,12 @@ M6mDL6NurBAW1pJlg8OT RootCertWithVidSubjectKeyID = "CE:A8:92:66:EA:E0:80:BD:2B:B5:68:E4:0B:07:C4:FA:2C:34:6D:31" RootCertWithVidVid = 65521 - IntermediateCertWithVidSubject = "MIGuMQswCQYDVQQGEwJVUzERMA8GA1UECAwITmV3IFlvcmsxETAPBgNVBAcMCE5ldyBZb3JrMRgwFgYDVQQKDA9FeGFtcGxlIENvbXBhbnkxGTAXBgNVBAsMEFRlc3RpbmcgRGl2aXNpb24xGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTEUMBIGCisGAQQBgqJ8AgEMBEZGRjExFDASBgorBgEEAYKifAICDARGRkYx" - IntermediateCertWithVidSubjectKeyID = "0E:8C:E8:C8:B8:AA:50:BC:25:85:56:B9:B1:9C:C2:C7:D9:C5:2F:17" + IntermediateCertWithVid1Subject = "MIGuMQswCQYDVQQGEwJVUzERMA8GA1UECAwITmV3IFlvcmsxETAPBgNVBAcMCE5ldyBZb3JrMRgwFgYDVQQKDA9FeGFtcGxlIENvbXBhbnkxGTAXBgNVBAsMEFRlc3RpbmcgRGl2aXNpb24xGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTEUMBIGCisGAQQBgqJ8AgEMBEZGRjExFDASBgorBgEEAYKifAICDARGRkYx" + IntermediateCertWithVid1SubjectKeyID = "0E:8C:E8:C8:B8:AA:50:BC:25:85:56:B9:B1:9C:C2:C7:D9:C5:2F:17" IntermediateCertWithVid1SerialNumber = "3" - IntermediateCertWithVid2SerialNumber = "4" IntermediateCertWithVid1Vid = 65521 + + IntermediateCertWithVid2SubjectKeyID = "0E:8C:E8:C8:B8:AA:50:BC:25:85:56:B9:B1:9C:C2:C7:D9:C5:2F:17" + IntermediateCertWithVid2SerialNumber = "4" IntermediateCertWithVid2Vid = 65522 ) diff --git a/integration_tests/grpc_rest/pki/helpers.go b/integration_tests/grpc_rest/pki/helpers.go index f895aaf62..e3defa51f 100644 --- a/integration_tests/grpc_rest/pki/helpers.go +++ b/integration_tests/grpc_rest/pki/helpers.go @@ -2031,7 +2031,7 @@ func Demo(suite *utils.TestSuite) { // Check approved certificates certs, _ = GetX509Cert(suite, testconstants.RootCertWithVidSubject, testconstants.RootCertWithVidSubjectKeyID) require.Equal(suite.T, 1, len(certs.Certs)) - certs, _ = GetX509Cert(suite, testconstants.IntermediateCertWithVidSubject, testconstants.IntermediateCertWithVidSubjectKeyID) + certs, _ = GetX509Cert(suite, testconstants.IntermediateCertWithVid1Subject, testconstants.IntermediateCertWithVid1SubjectKeyID) require.Equal(suite.T, 1, len(certs.Certs)) // Check that if root cert is VID scoped and rootVID != CertVID then adding an intermediate cert should fail @@ -2044,7 +2044,7 @@ func Demo(suite *utils.TestSuite) { require.Error(suite.T, err) // Check there is only one approved intermediate certificate - certs, _ = GetX509Cert(suite, testconstants.IntermediateCertWithVidSubject, testconstants.IntermediateCertWithVidSubjectKeyID) + certs, _ = GetX509Cert(suite, testconstants.IntermediateCertWithVid1Subject, testconstants.IntermediateCertWithVid1SubjectKeyID) require.Equal(suite.T, 1, len(certs.Certs)) require.Equal(suite.T, testconstants.IntermediateCertWithVid1SerialNumber, certs.Certs[0].SerialNumber) diff --git a/types/pki/errors.go b/types/pki/errors.go index 61dc3dc8f..0ab3869c7 100644 --- a/types/pki/errors.go +++ b/types/pki/errors.go @@ -47,7 +47,7 @@ var ( ErrCertificateVidNotEqualMsgVid = sdkerrors.Register(ModuleName, 436, "certificate's vid is not equal to the message vid") ErrMessageVidNotEqualRootCertVid = sdkerrors.Register(ModuleName, 437, "Message vid is not equal to ledger's root certificate vid") ErrCertNotChainedBack = sdkerrors.Register(ModuleName, 438, "Certificate is not chained back to a root certificate on DCL") - ErrCertVidNotEqualAccountVid = sdkerrors.Register(ModuleName, 439, "account's vid is not equal to ledger's certificate vid") + ErrCertVidNotEqualAccountVid = sdkerrors.Register(ModuleName, 439, "account's vid is not equal to certificate vid") ErrCertVidNotEqualToRootVid = sdkerrors.Register(ModuleName, 440, "certificate's vid is not equal to vid of root certificate ") ) @@ -207,22 +207,21 @@ func NewErrProvidedNotNocCertButExistingNoc(subject string, subjectKeyID string) subject, subjectKeyID) } -func NewErrRootCertVidNotEqualToAccountVidOrCertVid(rootVID int32, accountVID int32, certVID int32) error { - if rootVID != certVID { - return sdkerrors.Wrapf(ErrCertVidNotEqualToRootVid, - "Root certificate is VID scoped: A child certificate must be also VID scoped to the same VID as a root one: "+ - "Root certificate's VID = %v, Certificate's VID = %v", - rootVID, certVID) - } +func NewErrRootCertVidNotEqualToCertVid(rootVID int32, certVID int32) error { + return sdkerrors.Wrapf(ErrCertVidNotEqualToRootVid, + "A child certificate must be also VID scoped to the same VID as a root one: "+ + "Root certificate's VID = %v, Child certificate's VID = %v", + rootVID, certVID) +} +func NewErrRootCertVidNotEqualToAccountVid(rootVID int32, accountVID int32) error { return sdkerrors.Wrapf(ErrCertVidNotEqualAccountVid, - "Root certificate is VID scoped: "+ - "Only a Vendor associated with this VID can add a child certificate: "+ + "Only a Vendor associated with root certificate VID can add a child certificate: "+ "Root certificate's VID = %v, Account VID = %v", rootVID, accountVID) } -func NewErrAccountVidNotEqualToCertVid(accountVID int32, certVID int32) error { +func NewErrCertVidNotEqualToAccountVid(accountVID int32, certVID int32) error { return sdkerrors.Wrapf(ErrCertVidNotEqualAccountVid, "Certificate is VID scoped: Only a vendor associated with this VID can add this certificate "+ "Account VID = %v, Certificate's VID = %v", diff --git a/x/pki/handler_add_non_root_cert_test.go b/x/pki/handler_add_non_root_cert_test.go index 155c56341..cbdadb7a4 100644 --- a/x/pki/handler_add_non_root_cert_test.go +++ b/x/pki/handler_add_non_root_cert_test.go @@ -20,80 +20,68 @@ func TestHandler_AddX509Cert(t *testing.T) { rootCertificate := rootCertificate(setup.Trustee1) setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCertificate) - for i, role := range []dclauthtypes.AccountRole{ - dclauthtypes.Vendor, - dclauthtypes.CertificationCenter, - dclauthtypes.Trustee, - dclauthtypes.NodeAdmin, - } { - accAddress := GenerateAccAddress() - setup.AddAccount(accAddress, []dclauthtypes.AccountRole{role}, 1) - - // add x509 certificate - addX509Cert := types.NewMsgAddX509Cert(accAddress.String(), testconstants.IntermediateCertPem) - _, err := setup.Handler(setup.Ctx, addX509Cert) - require.NoError(t, err) - - // query certificate - certificate, _ := querySingleApprovedCertificate( - setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) - require.Equal(t, intermediateCertificate(accAddress), *certificate) - - certificateBySubjectKeyID, _ := queryAllApprovedCertificatesBySubjectKeyID(setup, testconstants.IntermediateSubjectKeyID) - require.Equal(t, 1, len(certificateBySubjectKeyID)) - require.Equal(t, i+1, len(certificateBySubjectKeyID[0].Certs)) - - certs := make([]*types.Certificate, 0) - certs = append(certs, certificate, certificateBySubjectKeyID[0].Certs[i]) - for _, cert := range certs { - // check - require.Equal(t, addX509Cert.Cert, cert.PemCert) - require.Equal(t, addX509Cert.Signer, cert.Owner) - require.Equal(t, testconstants.IntermediateSubject, cert.Subject) - require.Equal(t, testconstants.IntermediateSubjectKeyID, cert.SubjectKeyId) - require.Equal(t, testconstants.IntermediateSerialNumber, cert.SerialNumber) - require.False(t, cert.IsRoot) - require.Equal(t, testconstants.IntermediateIssuer, cert.Issuer) - require.Equal(t, testconstants.IntermediateAuthorityKeyID, cert.AuthorityKeyId) - require.Equal(t, testconstants.RootSubject, cert.RootSubject) - require.Equal(t, testconstants.RootSubjectKeyID, cert.RootSubjectKeyId) - } - - // check that unique certificate key is registered - require.True(t, setup.Keeper.IsUniqueCertificatePresent( - setup.Ctx, testconstants.IntermediateIssuer, testconstants.IntermediateSerialNumber)) - - // check that child certificates of issuer contains certificate identifier - issuerChildren, _ := queryChildCertificates( - setup, testconstants.IntermediateIssuer, testconstants.IntermediateAuthorityKeyID) - require.Equal(t, 1, len(issuerChildren.CertIds)) - require.Equal(t, - &types.CertificateIdentifier{ - Subject: testconstants.IntermediateSubject, - SubjectKeyId: testconstants.IntermediateSubjectKeyID, - }, - issuerChildren.CertIds[0]) - - // check that no proposed certificate has been created - _, err = queryProposedCertificate(setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) - require.Error(t, err) - require.Equal(t, codes.NotFound, status.Code(err)) - - // cleanup for next iteration - setup.Keeper.RemoveApprovedCertificates(setup.Ctx, - testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) - setup.Keeper.RemoveUniqueCertificate(setup.Ctx, - testconstants.IntermediateIssuer, testconstants.IntermediateSerialNumber) - setup.Keeper.RemoveChildCertificates(setup.Ctx, - testconstants.IntermediateIssuer, testconstants.IntermediateAuthorityKeyID) + accAddress := GenerateAccAddress() + setup.AddAccount(accAddress, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, 1) + + // add x509 certificate + addX509Cert := types.NewMsgAddX509Cert(accAddress.String(), testconstants.IntermediateCertPem) + _, err := setup.Handler(setup.Ctx, addX509Cert) + require.NoError(t, err) + + // query certificate + certificate, _ := querySingleApprovedCertificate( + setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) + require.Equal(t, intermediateCertificate(accAddress), *certificate) + + certificateBySubjectKeyID, _ := queryAllApprovedCertificatesBySubjectKeyID(setup, testconstants.IntermediateSubjectKeyID) + require.Equal(t, 1, len(certificateBySubjectKeyID)) + require.Equal(t, 1, len(certificateBySubjectKeyID[0].Certs)) + + certs := make([]*types.Certificate, 0) + certs = append(certs, certificate, certificateBySubjectKeyID[0].Certs[0]) + for _, cert := range certs { + // check + require.Equal(t, addX509Cert.Cert, cert.PemCert) + require.Equal(t, addX509Cert.Signer, cert.Owner) + require.Equal(t, testconstants.IntermediateSubject, cert.Subject) + require.Equal(t, testconstants.IntermediateSubjectKeyID, cert.SubjectKeyId) + require.Equal(t, testconstants.IntermediateSerialNumber, cert.SerialNumber) + require.False(t, cert.IsRoot) + require.Equal(t, testconstants.IntermediateIssuer, cert.Issuer) + require.Equal(t, testconstants.IntermediateAuthorityKeyID, cert.AuthorityKeyId) + require.Equal(t, testconstants.RootSubject, cert.RootSubject) + require.Equal(t, testconstants.RootSubjectKeyID, cert.RootSubjectKeyId) } + + // check that unique certificate key is registered + require.True(t, setup.Keeper.IsUniqueCertificatePresent( + setup.Ctx, testconstants.IntermediateIssuer, testconstants.IntermediateSerialNumber)) + + // check that child certificates of issuer contains certificate identifier + issuerChildren, _ := queryChildCertificates( + setup, testconstants.IntermediateIssuer, testconstants.IntermediateAuthorityKeyID) + require.Equal(t, 1, len(issuerChildren.CertIds)) + require.Equal(t, + &types.CertificateIdentifier{ + Subject: testconstants.IntermediateSubject, + SubjectKeyId: testconstants.IntermediateSubjectKeyID, + }, + issuerChildren.CertIds[0]) + + // check that no proposed certificate has been created + _, err = queryProposedCertificate(setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) + require.Error(t, err) + require.Equal(t, codes.NotFound, status.Code(err)) } func TestHandler_AddX509Cert_ForInvalidCertificate(t *testing.T) { setup := Setup(t) + accAddress := GenerateAccAddress() + setup.AddAccount(accAddress, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, 1) + // add x509 certificate - addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.StubCertPem) + addX509Cert := types.NewMsgAddX509Cert(accAddress.String(), testconstants.StubCertPem) _, err := setup.Handler(setup.Ctx, addX509Cert) require.Error(t, err) require.True(t, pkitypes.ErrInvalidCertificate.Is(err)) @@ -102,8 +90,11 @@ func TestHandler_AddX509Cert_ForInvalidCertificate(t *testing.T) { func TestHandler_AddX509Cert_ForRootCertificate(t *testing.T) { setup := Setup(t) + accAddress := GenerateAccAddress() + setup.AddAccount(accAddress, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, 1) + // add root certificate as leaf x509 certificate - addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.RootCertPem) + addX509Cert := types.NewMsgAddX509Cert(accAddress.String(), testconstants.RootCertPem) _, err := setup.Handler(setup.Ctx, addX509Cert) require.Error(t, err) require.True(t, pkitypes.ErrNonRootCertificateSelfSigned.Is(err)) @@ -116,8 +107,11 @@ func TestHandler_AddX509Cert_ForDuplicate(t *testing.T) { rootCertificate := rootCertificate(setup.Trustee1) setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCertificate) + accAddress := GenerateAccAddress() + setup.AddAccount(accAddress, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, 1) + // store intermediate certificate - addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) + addX509Cert := types.NewMsgAddX509Cert(accAddress.String(), testconstants.IntermediateCertPem) _, err := setup.Handler(setup.Ctx, addX509Cert) require.NoError(t, err) @@ -127,17 +121,17 @@ func TestHandler_AddX509Cert_ForDuplicate(t *testing.T) { require.True(t, pkitypes.ErrCertificateAlreadyExists.Is(err)) } -func TestHandler_AddX509Cert_ForNocCertificate(t *testing.T) { +func TestHandler_AddX509Cert_ForExistingNocCertificate(t *testing.T) { setup := Setup(t) // store root certificate rootCertificate := rootCertificate(setup.Trustee1) setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCertificate) - // Store the NOC certificate vendorAccAddress := GenerateAccAddress() setup.AddAccount(vendorAccAddress, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.Vid) + // Store the NOC certificate nocCertificate := intermediateCertificate(vendorAccAddress) nocCertificate.SerialNumber = testconstants.TestSerialNumber nocCertificate.IsNoc = true @@ -152,11 +146,47 @@ func TestHandler_AddX509Cert_ForNocCertificate(t *testing.T) { setup.Keeper.SetUniqueCertificate(setup.Ctx, uniqueCertificate) // store intermediate certificate - addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) + addX509Cert := types.NewMsgAddX509Cert(vendorAccAddress.String(), testconstants.IntermediateCertPem) _, err := setup.Handler(setup.Ctx, addX509Cert) + require.Error(t, err) require.True(t, pkitypes.ErrInappropriateCertificateType.Is(err)) } +func TestHandler_AddX509Cert_NoRootCert(t *testing.T) { + setup := Setup(t) + + vendorAccAddress := GenerateAccAddress() + setup.AddAccount(vendorAccAddress, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.Vid) + + // add intermediate certificate + intermediateCertificate := intermediateCertificate(vendorAccAddress) + setup.Keeper.AddApprovedCertificate(setup.Ctx, intermediateCertificate) + + // add leaf x509 certificate + addX509Cert := types.NewMsgAddX509Cert(vendorAccAddress.String(), testconstants.LeafCertPem) + _, err := setup.Handler(setup.Ctx, addX509Cert) + require.Error(t, err) + require.True(t, pkitypes.ErrInvalidCertificate.Is(err)) +} + +func TestHandler_AddX509Cert_RootIsNoc(t *testing.T) { + setup := Setup(t) + + accAddress := GenerateAccAddress() + setup.AddAccount(accAddress, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.IntermediateCertWithVid1Vid) + + // Add NOC root certificate + addNocX509RootCert := types.NewMsgAddNocX509RootCert(accAddress.String(), testconstants.RootCertPem) + _, err := setup.Handler(setup.Ctx, addNocX509RootCert) + require.NoError(t, err) + + // add x509 certificate + addX509Cert := types.NewMsgAddX509Cert(accAddress.String(), testconstants.IntermediateCertWithVid1) + _, err = setup.Handler(setup.Ctx, addX509Cert) + require.Error(t, err) + require.True(t, pkitypes.ErrCertVidNotEqualAccountVid.Is(err)) +} + func TestHandler_AddX509Cert_ForDifferentSerialNumber(t *testing.T) { setup := Setup(t) @@ -164,8 +194,11 @@ func TestHandler_AddX509Cert_ForDifferentSerialNumber(t *testing.T) { rootCertificate := rootCertificate(setup.Trustee1) setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCertificate) + vendorAccAddress := GenerateAccAddress() + setup.AddAccount(vendorAccAddress, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.Vid) + // store intermediate certificate with different serial number - intermediateCertificate := intermediateCertificate(setup.Trustee1) + intermediateCertificate := intermediateCertificate(vendorAccAddress) intermediateCertificate.SerialNumber = SerialNumber setup.Keeper.SetUniqueCertificate( setup.Ctx, @@ -174,7 +207,7 @@ func TestHandler_AddX509Cert_ForDifferentSerialNumber(t *testing.T) { setup.Keeper.AddApprovedCertificate(setup.Ctx, intermediateCertificate) // store intermediate certificate second time - addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) + addX509Cert := types.NewMsgAddX509Cert(vendorAccAddress.String(), testconstants.IntermediateCertPem) _, err := setup.Handler(setup.Ctx, addX509Cert) require.NoError(t, err) @@ -198,48 +231,14 @@ func TestHandler_AddX509Cert_ForDifferentSerialNumber(t *testing.T) { } } -func TestHandler_AddX509Cert_ForDifferentSerialNumberDifferentSigner(t *testing.T) { - setup := Setup(t) - - // store root certificate - rootCertificate := rootCertificate(setup.Trustee1) - setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCertificate) - - // store intermediate certificate with different serial number - intermediateCertificate := intermediateCertificate(setup.Trustee1) - intermediateCertificate.SerialNumber = SerialNumber - setup.Keeper.SetUniqueCertificate( - setup.Ctx, - uniqueCertificate(intermediateCertificate.Issuer, intermediateCertificate.SerialNumber), - ) - setup.Keeper.AddApprovedCertificate(setup.Ctx, intermediateCertificate) - - // store intermediate certificate second time - addX509Cert := types.NewMsgAddX509Cert(setup.Trustee2.String(), testconstants.IntermediateCertPem) - _, err := setup.Handler(setup.Ctx, addX509Cert) - require.Error(t, err) - require.True(t, sdkerrors.ErrUnauthorized.Is(err)) -} - func TestHandler_AddX509Cert_ForAbsentDirectParentCert(t *testing.T) { setup := Setup(t) - // add intermediate x509 certificate - addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) - _, err := setup.Handler(setup.Ctx, addX509Cert) - require.Error(t, err) - require.True(t, pkitypes.ErrInvalidCertificate.Is(err)) -} - -func TestHandler_AddX509Cert_ForNoRootCert(t *testing.T) { - setup := Setup(t) - - // add intermediate certificate - intermediateCertificate := intermediateCertificate(setup.Trustee1) - setup.Keeper.AddApprovedCertificate(setup.Ctx, intermediateCertificate) + vendorAccAddress := GenerateAccAddress() + setup.AddAccount(vendorAccAddress, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.Vid) - // add leaf x509 certificate - addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.LeafCertPem) + // add intermediate x509 certificate + addX509Cert := types.NewMsgAddX509Cert(vendorAccAddress.String(), testconstants.IntermediateCertPem) _, err := setup.Handler(setup.Ctx, addX509Cert) require.Error(t, err) require.True(t, pkitypes.ErrInvalidCertificate.Is(err)) @@ -254,8 +253,11 @@ func TestHandler_AddX509Cert_ForFailedCertificateVerification(t *testing.T) { testconstants.RootSerialNumber, setup.Trustee1.String(), []*types.Grant{}, []*types.Grant{}, testconstants.Vid) setup.Keeper.AddApprovedCertificate(setup.Ctx, invalidRootCertificate) + vendorAccAddress := GenerateAccAddress() + setup.AddAccount(vendorAccAddress, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.Vid) + // add intermediate x509 certificate - addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) + addX509Cert := types.NewMsgAddX509Cert(vendorAccAddress.String(), testconstants.IntermediateCertPem) _, err := setup.Handler(setup.Ctx, addX509Cert) require.Error(t, err) require.True(t, pkitypes.ErrInvalidCertificate.Is(err)) @@ -268,13 +270,16 @@ func TestHandler_AddX509Cert_ForTree(t *testing.T) { rootCertOptions := createTestRootCertOptions() proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOptions) + vendorAccAddress := GenerateAccAddress() + setup.AddAccount(vendorAccAddress, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.Vid) + // add intermediate x509 certificate - addIntermediateX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) + addIntermediateX509Cert := types.NewMsgAddX509Cert(vendorAccAddress.String(), testconstants.IntermediateCertPem) _, err := setup.Handler(setup.Ctx, addIntermediateX509Cert) require.NoError(t, err) // add leaf x509 certificate - addLeafX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.LeafCertPem) + addLeafX509Cert := types.NewMsgAddX509Cert(vendorAccAddress.String(), testconstants.LeafCertPem) _, err = setup.Handler(setup.Ctx, addLeafX509Cert) require.NoError(t, err) @@ -331,8 +336,11 @@ func TestHandler_AddX509Cert_EachChildCertRefersToTwoParentCerts(t *testing.T) { setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCert) setup.Keeper.SetUniqueCertificate(setup.Ctx, uniqueCertificate(rootCert.Subject, rootCert.SerialNumber)) + vendorAccAddress := GenerateAccAddress() + setup.AddAccount(vendorAccAddress, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.Vid) + // store intermediate certificate (it refers to two parent certificates) - intermediateCertificate := intermediateCertificate(setup.Trustee1) + intermediateCertificate := intermediateCertificate(vendorAccAddress) intermediateCertificate.SerialNumber = SerialNumber setup.Keeper.AddApprovedCertificate(setup.Ctx, intermediateCertificate) @@ -350,12 +358,12 @@ func TestHandler_AddX509Cert_EachChildCertRefersToTwoParentCerts(t *testing.T) { setup.Keeper.SetChildCertificates(setup.Ctx, rootChildCertificates) // store second intermediate certificate (it refers to two parent certificates) - addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) + addX509Cert := types.NewMsgAddX509Cert(vendorAccAddress.String(), testconstants.IntermediateCertPem) _, err := setup.Handler(setup.Ctx, addX509Cert) require.NoError(t, err) // store leaf certificate (it refers to two parent certificates) - addX509Cert = types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.LeafCertPem) + addX509Cert = types.NewMsgAddX509Cert(vendorAccAddress.String(), testconstants.LeafCertPem) _, err = setup.Handler(setup.Ctx, addX509Cert) require.NoError(t, err) @@ -396,30 +404,6 @@ func TestHandler_AddX509Cert_EachChildCertRefersToTwoParentCerts(t *testing.T) { require.Nil(t, leafCertChildren) } -func TestHandler_AddX509Cert_ByNotOwner(t *testing.T) { - setup := Setup(t) - - // store root certificate - rootCertificate := rootCertificate(setup.Trustee1) - setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCertificate) - - // Store an intermediate certificate with the first trustee as the owner - intermediateCertificate := intermediateCertificate(setup.Trustee1) - intermediateCertificate.SerialNumber = SerialNumber - setup.Keeper.AddApprovedCertificate(setup.Ctx, intermediateCertificate) - setup.Keeper.AddApprovedCertificateBySubjectKeyID(setup.Ctx, intermediateCertificate) - setup.Keeper.SetUniqueCertificate( - setup.Ctx, - uniqueCertificate(intermediateCertificate.Issuer, intermediateCertificate.SerialNumber), - ) - - // add an intermediate certificate with the same subject and SKID by second trustee - addX509Cert := types.NewMsgAddX509Cert(setup.Trustee2.String(), testconstants.IntermediateCertPem) - _, err := setup.Handler(setup.Ctx, addX509Cert) - require.Error(t, err) - require.True(t, sdkerrors.ErrUnauthorized.Is(err)) -} - func TestHandler_AddX509Cert_ByNotOwnerButSameVendor(t *testing.T) { setup := Setup(t) @@ -482,3 +466,188 @@ func TestHandler_AddX509Cert_ByNotOwnerAndOtherVendor(t *testing.T) { require.Error(t, err) require.True(t, sdkerrors.ErrUnauthorized.Is(err)) } + +func TestHandler_AddX509Cert_SendorNotVendor(t *testing.T) { + setup := Setup(t) + + // store root certificate + rootCertOptions := createRootWithVidOptions() + proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOptions) + + // add x509 certificate + addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertWithVid1) + _, err := setup.Handler(setup.Ctx, addX509Cert) + require.Error(t, err) + require.True(t, sdkerrors.ErrUnauthorized.Is(err)) +} + +func TestHandler_AddX509Cert_VIDScopedRoot(t *testing.T) { + setup := Setup(t) + + // store root certificate + rootCertOptions := createPAACertWithNumericVidOptions() + proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOptions) + + accAddress := GenerateAccAddress() + setup.AddAccount(accAddress, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.PAACertWithNumericVidVid) + + // add x509 certificate + addX509Cert := types.NewMsgAddX509Cert(accAddress.String(), testconstants.PAICertWithNumericPidVid) + _, err := setup.Handler(setup.Ctx, addX509Cert) + require.NoError(t, err) + + // query certificate + certs, _ := queryAllApprovedCertificates(setup) + require.Equal(t, 2, len(certs)) + intermediateCerts, _ := queryApprovedCertificates(setup, testconstants.PAICertWithNumericPidVidSubject, testconstants.PAICertWithNumericPidVidSubjectKeyID) + require.Equal(t, 1, len(intermediateCerts.Certs)) + require.Equal(t, testconstants.PAICertWithNumericPidVidSubject, intermediateCerts.Certs[0].Subject) + require.Equal(t, testconstants.PAICertWithNumericPidVidSubjectKeyID, intermediateCerts.Certs[0].SubjectKeyId) +} + +func TestHandler_AddX509Cert_NonVIDScopedRoot(t *testing.T) { + accAddress := GenerateAccAddress() + + cases := []struct { + name string + rootCertOptions *rootCertOptions + childCert string + childCertSubject string + childCertSubjectKeyId string + accountVid int32 + }{ + { + name: "VidScopedChild", + rootCertOptions: createPAACertNoVidOptions(testconstants.PAICertWithVidVid), + childCert: testconstants.PAICertWithNumericVid, + childCertSubject: testconstants.PAICertWithNumericVidSubject, + childCertSubjectKeyId: testconstants.PAICertWithNumericVidSubjectKeyID, + accountVid: testconstants.PAICertWithVidVid, + }, + { + name: "NonVidScopedChild", + rootCertOptions: createTestRootCertOptions(), + childCert: testconstants.IntermediateCertPem, + childCertSubject: testconstants.IntermediateSubject, + childCertSubjectKeyId: testconstants.IntermediateSubjectKeyID, + accountVid: testconstants.Vid, + }, + } + + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + setup := Setup(t) + // store root certificate + proposeAndApproveRootCertificate(setup, setup.Trustee1, tc.rootCertOptions) + + // add vendor account + setup.AddAccount(accAddress, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, tc.accountVid) + + // add x509 certificate + addX509Cert := types.NewMsgAddX509Cert(accAddress.String(), tc.childCert) + _, err := setup.Handler(setup.Ctx, addX509Cert) + require.NoError(t, err) + + // query certificate + certs, _ := queryAllApprovedCertificates(setup) + require.Equal(t, 2, len(certs)) + intermediateCerts, _ := queryApprovedCertificates(setup, tc.childCertSubject, tc.childCertSubjectKeyId) + require.Equal(t, 1, len(intermediateCerts.Certs)) + require.Equal(t, tc.childCertSubject, intermediateCerts.Certs[0].Subject) + require.Equal(t, tc.childCertSubjectKeyId, intermediateCerts.Certs[0].SubjectKeyId) + }) + } +} + +func TestHandler_AddX509Cert_VIDScopedRoot_NegativeCases(t *testing.T) { + accAddress := GenerateAccAddress() + + cases := []struct { + name string + rootCertOptions *rootCertOptions + childCert string + accountVid int32 + err error + }{ + // { + // name: "NonVidScopedChild", + // rootCertOptions: createRootWithVidOptions(), + // childCert: testconstants.IntermediateCertPem, + // accountVid: testconstants.PAICertWithVidVid, + // err: pkitypes.ErrCertVidNotEqualToRootVid, + // }, + { + name: "IncorrectChildVid", + rootCertOptions: createRootWithVidOptions(), + childCert: testconstants.IntermediateCertWithVid2, + accountVid: testconstants.RootCertWithVidVid, + err: pkitypes.ErrCertVidNotEqualToRootVid, + }, + { + name: "IncorrectAccountVid", + rootCertOptions: createRootWithVidOptions(), + childCert: testconstants.IntermediateCertWithVid1, + accountVid: testconstants.Vid, + err: pkitypes.ErrCertVidNotEqualAccountVid, + }, + } + + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + setup := Setup(t) + // store root certificate + proposeAndApproveRootCertificate(setup, setup.Trustee1, tc.rootCertOptions) + + // add vendor account + setup.AddAccount(accAddress, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, tc.accountVid) + + // add x509 certificate + addX509Cert := types.NewMsgAddX509Cert(accAddress.String(), tc.childCert) + _, err := setup.Handler(setup.Ctx, addX509Cert) + require.ErrorIs(t, err, tc.err) + }) + } +} + +func TestHandler_AddX509Cert_NonVIDScopedRoot_NegativeCases(t *testing.T) { + accAddress := GenerateAccAddress() + + cases := []struct { + name string + rootCertOptions *rootCertOptions + childCert string + accountVid int32 + err error + }{ + { + name: "IncorrectChildVid", + rootCertOptions: createPAACertNoVidOptions(testconstants.Vid), + childCert: testconstants.PAICertWithNumericVid, + accountVid: testconstants.Vid, + err: pkitypes.ErrCertVidNotEqualAccountVid, + }, + { + name: "IncorrectAccountVid", + rootCertOptions: createPAACertNoVidOptions(testconstants.PAICertWithVidVid), + childCert: testconstants.PAICertWithNumericVid, + accountVid: testconstants.Vid, + err: pkitypes.ErrCertVidNotEqualAccountVid, + }, + } + + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + setup := Setup(t) + // store root certificate + proposeAndApproveRootCertificate(setup, setup.Trustee1, tc.rootCertOptions) + + // add vendor account + setup.AddAccount(accAddress, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, tc.accountVid) + + // add x509 certificate + addX509Cert := types.NewMsgAddX509Cert(accAddress.String(), tc.childCert) + _, err := setup.Handler(setup.Ctx, addX509Cert) + require.ErrorIs(t, err, tc.err) + }) + } +} diff --git a/x/pki/handler_remove_non_root_cert_test.go b/x/pki/handler_remove_non_root_cert_test.go index cca6791ad..aaa788165 100644 --- a/x/pki/handler_remove_non_root_cert_test.go +++ b/x/pki/handler_remove_non_root_cert_test.go @@ -189,6 +189,7 @@ func TestHandler_RemoveX509Cert_RevokedCertificate(t *testing.T) { testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, testconstants.IntermediateSerialNumber, + false, testconstants.Info, ) _, err = setup.Handler(setup.Ctx, revokeX509Cert) diff --git a/x/pki/handler_revoke_non_root_cert_test.go b/x/pki/handler_revoke_non_root_cert_test.go index 5edcc64e9..9d531802c 100644 --- a/x/pki/handler_revoke_non_root_cert_test.go +++ b/x/pki/handler_revoke_non_root_cert_test.go @@ -21,7 +21,13 @@ func TestHandler_RevokeX509CertRoot_CertificateDoesNotExistBySerialNumber(t *tes // revoke x509 certificate revokeX509Cert := types.NewMsgProposeRevokeX509RootCert( - setup.Trustee1.String(), testconstants.RootSubject, testconstants.RootSubjectKeyID, "invalid", testconstants.Info) + setup.Trustee1.String(), + testconstants.RootSubject, + testconstants.RootSubjectKeyID, + "invalid", + false, + testconstants.Info, + ) _, err := setup.Handler(setup.Ctx, revokeX509Cert) require.Error(t, err) require.True(t, pkitypes.ErrCertificateDoesNotExist.Is(err)) @@ -31,7 +37,13 @@ func TestHandler_RevokeX509Cert_CertificateDoesNotExist(t *testing.T) { // revoke x509 certificate revokeX509Cert := types.NewMsgRevokeX509Cert( - setup.Trustee1.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, testconstants.IntermediateSerialNumber, testconstants.Info) + setup.Trustee1.String(), + testconstants.IntermediateSubject, + testconstants.IntermediateSubjectKeyID, + testconstants.IntermediateSerialNumber, + false, + testconstants.Info, + ) _, err := setup.Handler(setup.Ctx, revokeX509Cert) require.Error(t, err) require.True(t, pkitypes.ErrCertificateDoesNotExist.Is(err)) @@ -50,7 +62,13 @@ func TestHandler_RevokeX509Cert_CertificateDoesNotExistBySerialNumber(t *testing // revoke x509 certificate revokeX509Cert := types.NewMsgRevokeX509Cert( - setup.Trustee1.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, "invalid", testconstants.Info) + setup.Trustee1.String(), + testconstants.IntermediateSubject, + testconstants.IntermediateSubjectKeyID, + "invalid", + false, + testconstants.Info, + ) _, err = setup.Handler(setup.Ctx, revokeX509Cert) require.Error(t, err) require.True(t, pkitypes.ErrCertificateDoesNotExist.Is(err)) @@ -65,7 +83,13 @@ func TestHandler_RevokeX509Cert_ForRootCertificate(t *testing.T) { // revoke x509 root certificate revokeX509Cert := types.NewMsgRevokeX509Cert( - setup.Trustee1.String(), testconstants.RootSubject, testconstants.RootSubjectKeyID, testconstants.RootSerialNumber, testconstants.Info) + setup.Trustee1.String(), + testconstants.RootSubject, + testconstants.RootSubjectKeyID, + testconstants.RootSerialNumber, + false, + testconstants.Info, + ) _, err := setup.Handler(setup.Ctx, revokeX509Cert) require.Error(t, err) require.True(t, pkitypes.ErrInappropriateCertificateType.Is(err)) @@ -96,7 +120,13 @@ func TestHandler_RevokeX509Cert_ForTree(t *testing.T) { // revoke x509 certificate revokeX509Cert := types.NewMsgRevokeX509Cert( - setup.Trustee1.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, "", testconstants.Info) + setup.Trustee1.String(), + testconstants.IntermediateSubject, + testconstants.IntermediateSubjectKeyID, + "", + false, + testconstants.Info, + ) _, err = setup.Handler(setup.Ctx, revokeX509Cert) require.NoError(t, err) @@ -166,7 +196,13 @@ func TestHandler_RevokeX509Cert_ByNotOwner(t *testing.T) { // revoke x509 certificate by another account revokeX509Cert := types.NewMsgRevokeX509Cert( - anotherTrustee.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, testconstants.IntermediateSerialNumber, testconstants.Info) + anotherTrustee.String(), + testconstants.IntermediateSubject, + testconstants.IntermediateSubjectKeyID, + testconstants.IntermediateSerialNumber, + false, + testconstants.Info, + ) _, err = setup.Handler(setup.Ctx, revokeX509Cert) require.Error(t, err) require.True(t, sdkerrors.ErrUnauthorized.Is(err)) @@ -198,6 +234,7 @@ func TestHandler_RevokeX509Cert_ByNotOwnerButSameVendor(t *testing.T) { testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, testconstants.IntermediateSerialNumber, + false, testconstants.Info, ) _, err = setup.Handler(setup.Ctx, revokeX509Cert) @@ -252,7 +289,13 @@ func TestHandler_RevokeX509Cert_ByNotOwnerAndOtherVendor(t *testing.T) { // revoke x509 certificate by second vendor account revokeX509Cert := types.NewMsgRevokeX509Cert( - vendorAccAddress2.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, testconstants.IntermediateSerialNumber, testconstants.Info) + vendorAccAddress2.String(), + testconstants.IntermediateSubject, + testconstants.IntermediateSubjectKeyID, + testconstants.IntermediateSerialNumber, + false, + testconstants.Info, + ) _, err = setup.Handler(setup.Ctx, revokeX509Cert) require.Error(t, err) require.True(t, sdkerrors.ErrUnauthorized.Is(err)) @@ -289,7 +332,7 @@ func TestHandler_RevokeX509Cert(t *testing.T) { // revoke x509 certificate revokeX509Cert := types.NewMsgRevokeX509Cert( - accAddress.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, "", testconstants.Info) + accAddress.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, "", false, testconstants.Info) _, err = setup.Handler(setup.Ctx, revokeX509Cert) require.NoError(t, err) @@ -362,9 +405,9 @@ func TestHandler_RevokeX509Cert_BySerialNumber(t *testing.T) { require.Equal(t, 3, len(allCerts)) require.Equal(t, 4, len(allCerts[0].Certs)+len(allCerts[1].Certs)+len(allCerts[2].Certs)) - // revoke intermediate certificate + // revoke only an intermediate certificate revokeX509Cert := types.NewMsgRevokeX509Cert( - setup.Trustee1.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, testconstants.IntermediateSerialNumber, testconstants.Info) + setup.Trustee1.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, testconstants.IntermediateSerialNumber, false, testconstants.Info) _, err = setup.Handler(setup.Ctx, revokeX509Cert) require.NoError(t, err) @@ -373,13 +416,16 @@ func TestHandler_RevokeX509Cert_BySerialNumber(t *testing.T) { require.Error(t, err) require.Equal(t, codes.NotFound, status.Code(err)) - // check that only root and two intermediate certificates exists + // check that only root, intermediate and leaf certificates exists allCerts, _ = queryAllApprovedCertificates(setup) require.Equal(t, 3, len(allCerts)) require.Equal(t, 3, len(allCerts[0].Certs)+len(allCerts[1].Certs)+len(allCerts[2].Certs)) intermediateCerts, _ := queryApprovedCertificates(setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) require.Equal(t, 1, len(intermediateCerts.Certs)) require.Equal(t, SerialNumber, intermediateCerts.Certs[0].SerialNumber) + leafCerts, _ := queryApprovedCertificates(setup, testconstants.LeafSubject, testconstants.LeafSubjectKeyID) + require.Equal(t, 1, len(leafCerts.Certs)) + require.Equal(t, testconstants.LeafSerialNumber, leafCerts.Certs[0].SerialNumber) // query and check revoked certificate revokedCertificate, _ := querySingleRevokedCertificate(setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) @@ -388,9 +434,15 @@ func TestHandler_RevokeX509Cert_BySerialNumber(t *testing.T) { require.Equal(t, testconstants.IntermediateSubjectKeyID, revokedCertificate.SubjectKeyId) require.Equal(t, testconstants.IntermediateSerialNumber, revokedCertificate.SerialNumber) - // revoke intermediate certificate + // revoke intermediate and leaf certificates revokeX509Cert = types.NewMsgRevokeX509Cert( - setup.Trustee1.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, SerialNumber, testconstants.Info) + setup.Trustee1.String(), + testconstants.IntermediateSubject, + testconstants.IntermediateSubjectKeyID, + SerialNumber, + true, + testconstants.Info, + ) _, err = setup.Handler(setup.Ctx, revokeX509Cert) require.NoError(t, err) @@ -409,4 +461,10 @@ func TestHandler_RevokeX509Cert_BySerialNumber(t *testing.T) { require.Equal(t, 2, len(revokedCerts.Certs)) require.Equal(t, testconstants.IntermediateSubject, revokedCerts.Subject) require.Equal(t, testconstants.IntermediateSubjectKeyID, revokedCerts.SubjectKeyId) + + // query and check revoked certificate + revokedCerts, _ = queryRevokedCertificates(setup, testconstants.LeafSubject, testconstants.LeafSubjectKeyID) + require.Equal(t, 1, len(revokedCerts.Certs)) + require.Equal(t, testconstants.LeafSubject, revokedCerts.Subject) + require.Equal(t, testconstants.LeafSubjectKeyID, revokedCerts.SubjectKeyId) } diff --git a/x/pki/handler_test.go b/x/pki/handler_test.go index 2314ec22a..93ede9a48 100644 --- a/x/pki/handler_test.go +++ b/x/pki/handler_test.go @@ -1531,6 +1531,16 @@ func createTestRootCertOptions() *rootCertOptions { } } +func createRootWithVidOptions() *rootCertOptions { + return &rootCertOptions{ + pemCert: testconstants.RootCertWithVid, + info: testconstants.Info, + subject: testconstants.RootCertWithVidSubject, + subjectKeyID: testconstants.RootCertWithVidSubjectKeyID, + vid: testconstants.RootCertWithVidVid, + } +} + func createPAACertWithNumericVidOptions() *rootCertOptions { return &rootCertOptions{ pemCert: testconstants.PAACertWithNumericVid, diff --git a/x/pki/keeper/approved_certificates.go b/x/pki/keeper/approved_certificates.go index 0b6c7a869..20fa5215d 100644 --- a/x/pki/keeper/approved_certificates.go +++ b/x/pki/keeper/approved_certificates.go @@ -41,22 +41,6 @@ func (k Keeper) GetApprovedCertificates( return val, true } -func (k Keeper) GetApprovedCertificateBySerialNumber( - ctx sdk.Context, - subject string, - subjectKeyID string, - serialNumber string, -) (val types.Certificate, found bool) { - certs, found := k.GetApprovedCertificates(ctx, subject, subjectKeyID) - if !found { - return val, false - } - - cert, found := findCertificate(serialNumber, &certs.Certs) - - return *cert, found -} - // RemoveApprovedCertificates removes a approvedCertificates from the store. func (k Keeper) RemoveApprovedCertificates( ctx sdk.Context, diff --git a/x/pki/keeper/keeper.go b/x/pki/keeper/keeper.go index f9bf084b3..d14df518c 100644 --- a/x/pki/keeper/keeper.go +++ b/x/pki/keeper/keeper.go @@ -51,7 +51,7 @@ func (k Keeper) CertificateRejectApprovalsCount(ctx sdk.Context, authKeeper type return authKeeper.CountAccountsWithRole(ctx, authTypes.Trustee) - k.CertificateApprovalsCount(ctx, authKeeper) + 1 } -func (k Keeper) EnsureCertificateOwnership(ctx sdk.Context, certificate *types.Certificate, signer string) error { +func (k Keeper) EnsureSenderAndOwnerVidMatch(ctx sdk.Context, certificate *types.Certificate, signer string) error { // get signer VID signerAddr, err := sdk.AccAddressFromBech32(signer) if err != nil { @@ -70,12 +70,8 @@ func (k Keeper) EnsureCertificateOwnership(ctx sdk.Context, certificate *types.C ownerAccount, _ := k.dclauthKeeper.GetAccountO(ctx, ownerAddr) ownerVid := ownerAccount.VendorID - if ownerVid != 0 { - if signerVid != ownerVid { - return pkitypes.NewErrUnauthorizedCertVendor(certificate.Subject, certificate.SubjectKeyId, ownerVid) - } - } else if signer != certificate.Owner { - return pkitypes.NewErrUnauthorizedCertOwner(certificate.Subject, certificate.SubjectKeyId) + if signerVid != ownerVid { + return pkitypes.NewErrUnauthorizedCertVendor(certificate.Subject, certificate.SubjectKeyId, ownerVid) } return nil diff --git a/x/pki/keeper/msg_server_add_x_509_cert.go b/x/pki/keeper/msg_server_add_x_509_cert.go index 07136868d..fde211288 100644 --- a/x/pki/keeper/msg_server_add_x_509_cert.go +++ b/x/pki/keeper/msg_server_add_x_509_cert.go @@ -6,6 +6,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" pkitypes "github.com/zigbee-alliance/distributed-compliance-ledger/types/pki" + dclauthtypes "github.com/zigbee-alliance/distributed-compliance-ledger/x/dclauth/types" "github.com/zigbee-alliance/distributed-compliance-ledger/x/pki/types" "github.com/zigbee-alliance/distributed-compliance-ledger/x/pki/x509" ) @@ -13,6 +14,16 @@ import ( func (k msgServer) AddX509Cert(goCtx context.Context, msg *types.MsgAddX509Cert) (*types.MsgAddX509CertResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) + signerAddr, err := sdk.AccAddressFromBech32(msg.Signer) + if err != nil { + return nil, pkitypes.NewErrInvalidAddress(err) + } + + // check if signer has vendor role + if !k.dclauthKeeper.HasRole(ctx, signerAddr, dclauthtypes.Vendor) { + return nil, pkitypes.NewErrUnauthorizedRole("MsgAddNocX509RootCert", dclauthtypes.Vendor) + } + // decode pem certificate x509Certificate, err := x509.DecodeX509Certificate(msg.Cert) if err != nil { @@ -47,46 +58,31 @@ func (k msgServer) AddX509Cert(goCtx context.Context, msg *types.MsgAddX509Cert) return nil, pkitypes.NewErrProvidedNotNocCertButExistingNoc(x509Certificate.Subject, x509Certificate.SubjectKeyID) } - if err = k.EnsureCertificateOwnership(ctx, existingCertificate, msg.Signer); err != nil { + if err = k.EnsureSenderAndOwnerVidMatch(ctx, existingCertificate, msg.Signer); err != nil { return nil, err } } // Valid certificate chain must be built for new certificate - rootCert, err := k.verifyCertificate(ctx, x509Certificate) + decodedRootCert, err := k.verifyCertificate(ctx, x509Certificate) if err != nil { return nil, err } - // Check Root and Intermediate certs for VID scoping - rootVid, err := x509.GetVidFromSubject(x509.ToSubjectAsText(rootCert.SubjectAsText)) - if err != nil { - return nil, pkitypes.NewErrInvalidVidFormat(err) - } - childVid, err := x509.GetVidFromSubject(x509Certificate.SubjectAsText) - if err != nil { - return nil, pkitypes.NewErrInvalidVidFormat(err) - } - signerAddr, err := sdk.AccAddressFromBech32(msg.Signer) - if err != nil { - return nil, pkitypes.NewErrInvalidAddress(err) - } - signerAccount, _ := k.dclauthKeeper.GetAccountO(ctx, signerAddr) - accountVID := signerAccount.VendorID + // get the full structure of the root certificate which contains the necessary fields for further validation + approvedRootCerts, _ := k.GetApprovedCertificates(ctx, decodedRootCert.Subject, decodedRootCert.SubjectKeyID) + if len(approvedRootCerts.Certs) == 0 { + return nil, pkitypes.NewErrRootCertificateDoesNotExist(decodedRootCert.Subject, decodedRootCert.SubjectKeyID) + } + rootCert := approvedRootCerts.Certs[0] - if rootVid != 0 { - // If added under a VID scoped root CA: Intermediate cert must be also VID scoped to the same VID as a root one. - // Only a Vendor associated with this VID can add an intermediate certificate. So `rootVid == childVid == accountVID` - // condition must hold - if rootVid != childVid || rootVid != accountVID { - return nil, pkitypes.NewErrRootCertVidNotEqualToAccountVidOrCertVid(rootVid, accountVID, childVid) - } - // If added under a non-VID scoped root CA associated with a VID: Intermediate cert must be either VID scoped to the same VID, or non-VID scoped. - // Only a Vendor associated with this VID can add an intermediate certificate. - } else if childVid != 0 && childVid != accountVID { - return nil, pkitypes.NewErrAccountVidNotEqualToCertVid(accountVID, childVid) + // Root certificate must not be NOC + if rootCert.IsNoc { + return nil, pkitypes.NewErrProvidedNotNocCertButExistingNoc(x509Certificate.Subject, x509Certificate.SubjectKeyID) } + k.ensureCertsAndSenderVidMatch(ctx, rootCert, x509Certificate, signerAddr) + // create new certificate certificate := types.NewNonRootCertificate( msg.Cert, @@ -97,7 +93,7 @@ func (k msgServer) AddX509Cert(goCtx context.Context, msg *types.MsgAddX509Cert) x509Certificate.Issuer, x509Certificate.AuthorityKeyID, rootCert.Subject, - rootCert.SubjectKeyID, + rootCert.SubjectKeyId, msg.Signer, ) @@ -127,3 +123,49 @@ func (k msgServer) AddX509Cert(goCtx context.Context, msg *types.MsgAddX509Cert) return &types.MsgAddX509CertResponse{}, nil } + +func (k msgServer) ensureCertsAndSenderVidMatch( + ctx sdk.Context, + rootCert *types.Certificate, + childCert *x509.Certificate, + signerAddr sdk.AccAddress, +) error { + // Check Root and Intermediate certs for VID scoping + rootVid, err := x509.GetVidFromSubject(x509.ToSubjectAsText(rootCert.SubjectAsText)) + if err != nil { + return pkitypes.NewErrInvalidVidFormat(err) + } + childVid, err := x509.GetVidFromSubject(childCert.SubjectAsText) + if err != nil { + return pkitypes.NewErrInvalidVidFormat(err) + } + + signerAccount, _ := k.dclauthKeeper.GetAccountO(ctx, signerAddr) + accountVID := signerAccount.VendorID + + if rootVid != 0 { + // If added under a VID scoped root CA: + // Child certificate must be also VID scoped to the same VID as a root one + if rootVid != childVid { + return pkitypes.NewErrRootCertVidNotEqualToCertVid(rootVid, childVid) + } + + // Only a Vendor associated with root certificate's VID can add an intermediate certificate + if rootVid != accountVID { + return pkitypes.NewErrRootCertVidNotEqualToAccountVid(rootVid, accountVID) + } + } else { + // If added under a non-VID scoped root CA: + // Child certificate must be either VID scoped to the same VID, or non-VID scoped. + if childVid != 0 && childVid != accountVID { + return pkitypes.NewErrCertVidNotEqualToAccountVid(accountVID, childVid) + } + + // Only a Vendor associated with root certificate VID can add an intermediate certificate. + if rootCert.Vid != accountVID { + return pkitypes.NewErrRootCertVidNotEqualToAccountVid(rootCert.Vid, accountVID) + } + } + + return nil +} diff --git a/x/pki/keeper/msg_server_remove_x_509_cert.go b/x/pki/keeper/msg_server_remove_x_509_cert.go index c36211154..49079b67e 100644 --- a/x/pki/keeper/msg_server_remove_x_509_cert.go +++ b/x/pki/keeper/msg_server_remove_x_509_cert.go @@ -6,12 +6,23 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" pkitypes "github.com/zigbee-alliance/distributed-compliance-ledger/types/pki" + dclauthtypes "github.com/zigbee-alliance/distributed-compliance-ledger/x/dclauth/types" "github.com/zigbee-alliance/distributed-compliance-ledger/x/pki/types" ) func (k msgServer) RemoveX509Cert(goCtx context.Context, msg *types.MsgRemoveX509Cert) (*types.MsgRemoveX509CertResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) + signerAddr, err := sdk.AccAddressFromBech32(msg.Signer) + if err != nil { + return nil, pkitypes.NewErrInvalidAddress(err) + } + + // check if signer has vendor role + if !k.dclauthKeeper.HasRole(ctx, signerAddr, dclauthtypes.Vendor) { + return nil, pkitypes.NewErrUnauthorizedRole("MsgAddNocX509RootCert", dclauthtypes.Vendor) + } + aprCerts, foundApproved := k.GetApprovedCertificates(ctx, msg.Subject, msg.SubjectKeyId) revCerts, foundRevoked := k.GetRevokedCertificates(ctx, msg.Subject, msg.SubjectKeyId) certificates := aprCerts.Certs @@ -24,7 +35,7 @@ func (k msgServer) RemoveX509Cert(goCtx context.Context, msg *types.MsgRemoveX50 return nil, pkitypes.NewErrMessageRemoveRoot(msg.Subject, msg.SubjectKeyId) } - if err := k.EnsureCertificateOwnership(ctx, certificates[0], msg.Signer); err != nil { + if err := k.EnsureSenderAndOwnerVidMatch(ctx, certificates[0], msg.Signer); err != nil { return nil, err } diff --git a/x/pki/keeper/msg_server_revoke_x_509_cert.go b/x/pki/keeper/msg_server_revoke_x_509_cert.go index fa551c7e7..a83c5840f 100644 --- a/x/pki/keeper/msg_server_revoke_x_509_cert.go +++ b/x/pki/keeper/msg_server_revoke_x_509_cert.go @@ -5,12 +5,23 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" pkitypes "github.com/zigbee-alliance/distributed-compliance-ledger/types/pki" + dclauthtypes "github.com/zigbee-alliance/distributed-compliance-ledger/x/dclauth/types" "github.com/zigbee-alliance/distributed-compliance-ledger/x/pki/types" ) func (k msgServer) RevokeX509Cert(goCtx context.Context, msg *types.MsgRevokeX509Cert) (*types.MsgRevokeX509CertResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) + signerAddr, err := sdk.AccAddressFromBech32(msg.Signer) + if err != nil { + return nil, pkitypes.NewErrInvalidAddress(err) + } + + // check if signer has vendor role + if !k.dclauthKeeper.HasRole(ctx, signerAddr, dclauthtypes.Vendor) { + return nil, pkitypes.NewErrUnauthorizedRole("MsgAddNocX509RootCert", dclauthtypes.Vendor) + } + certificates, _ := k.GetApprovedCertificates(ctx, msg.Subject, msg.SubjectKeyId) if len(certificates.Certs) == 0 { return nil, pkitypes.NewErrCertificateDoesNotExist(msg.Subject, msg.SubjectKeyId) @@ -20,7 +31,7 @@ func (k msgServer) RevokeX509Cert(goCtx context.Context, msg *types.MsgRevokeX50 return nil, pkitypes.NewErrMessageRemoveRoot(msg.Subject, msg.SubjectKeyId) } - if err := k.EnsureCertificateOwnership(ctx, certificates.Certs[0], msg.Signer); err != nil { + if err := k.EnsureSenderAndOwnerVidMatch(ctx, certificates.Certs[0], msg.Signer); err != nil { return nil, err } From cfc895aad80e99a9c4123e6d6faff239794771d9 Mon Sep 17 00:00:00 2001 From: "aziz.karabashov" Date: Mon, 4 Mar 2024 18:01:20 +0500 Subject: [PATCH 04/14] Fix unit tests --- types/pki/errors.go | 4 + x/pki/handler_add_non_root_cert_test.go | 45 ++-- x/pki/handler_remove_non_root_cert_test.go | 133 +++++++---- x/pki/handler_revoke_non_root_cert_test.go | 252 ++++++++++----------- x/pki/handler_test.go | 49 +++- x/pki/keeper/msg_server_add_x_509_cert.go | 11 +- 6 files changed, 274 insertions(+), 220 deletions(-) diff --git a/types/pki/errors.go b/types/pki/errors.go index 0ab3869c7..5fbe2462c 100644 --- a/types/pki/errors.go +++ b/types/pki/errors.go @@ -207,6 +207,10 @@ func NewErrProvidedNotNocCertButExistingNoc(subject string, subjectKeyID string) subject, subjectKeyID) } +func NewErrProvidedNotNocCertButRootNoc() error { + return sdkerrors.Wrapf(ErrInappropriateCertificateType, "The root is NOC certificate, but the provided certificate is not") +} + func NewErrRootCertVidNotEqualToCertVid(rootVID int32, certVID int32) error { return sdkerrors.Wrapf(ErrCertVidNotEqualToRootVid, "A child certificate must be also VID scoped to the same VID as a root one: "+ diff --git a/x/pki/handler_add_non_root_cert_test.go b/x/pki/handler_add_non_root_cert_test.go index cbdadb7a4..879aba78e 100644 --- a/x/pki/handler_add_non_root_cert_test.go +++ b/x/pki/handler_add_non_root_cert_test.go @@ -83,8 +83,7 @@ func TestHandler_AddX509Cert_ForInvalidCertificate(t *testing.T) { // add x509 certificate addX509Cert := types.NewMsgAddX509Cert(accAddress.String(), testconstants.StubCertPem) _, err := setup.Handler(setup.Ctx, addX509Cert) - require.Error(t, err) - require.True(t, pkitypes.ErrInvalidCertificate.Is(err)) + require.ErrorIs(t, err, pkitypes.ErrInvalidCertificate) } func TestHandler_AddX509Cert_ForRootCertificate(t *testing.T) { @@ -96,8 +95,7 @@ func TestHandler_AddX509Cert_ForRootCertificate(t *testing.T) { // add root certificate as leaf x509 certificate addX509Cert := types.NewMsgAddX509Cert(accAddress.String(), testconstants.RootCertPem) _, err := setup.Handler(setup.Ctx, addX509Cert) - require.Error(t, err) - require.True(t, pkitypes.ErrNonRootCertificateSelfSigned.Is(err)) + require.ErrorIs(t, err, pkitypes.ErrNonRootCertificateSelfSigned) } func TestHandler_AddX509Cert_ForDuplicate(t *testing.T) { @@ -117,8 +115,7 @@ func TestHandler_AddX509Cert_ForDuplicate(t *testing.T) { // store intermediate certificate second time _, err = setup.Handler(setup.Ctx, addX509Cert) - require.Error(t, err) - require.True(t, pkitypes.ErrCertificateAlreadyExists.Is(err)) + require.ErrorIs(t, err, pkitypes.ErrCertificateAlreadyExists) } func TestHandler_AddX509Cert_ForExistingNocCertificate(t *testing.T) { @@ -148,8 +145,7 @@ func TestHandler_AddX509Cert_ForExistingNocCertificate(t *testing.T) { // store intermediate certificate addX509Cert := types.NewMsgAddX509Cert(vendorAccAddress.String(), testconstants.IntermediateCertPem) _, err := setup.Handler(setup.Ctx, addX509Cert) - require.Error(t, err) - require.True(t, pkitypes.ErrInappropriateCertificateType.Is(err)) + require.ErrorIs(t, err, pkitypes.ErrInappropriateCertificateType) } func TestHandler_AddX509Cert_NoRootCert(t *testing.T) { @@ -165,8 +161,7 @@ func TestHandler_AddX509Cert_NoRootCert(t *testing.T) { // add leaf x509 certificate addX509Cert := types.NewMsgAddX509Cert(vendorAccAddress.String(), testconstants.LeafCertPem) _, err := setup.Handler(setup.Ctx, addX509Cert) - require.Error(t, err) - require.True(t, pkitypes.ErrInvalidCertificate.Is(err)) + require.ErrorIs(t, err, pkitypes.ErrInvalidCertificate) } func TestHandler_AddX509Cert_RootIsNoc(t *testing.T) { @@ -181,10 +176,9 @@ func TestHandler_AddX509Cert_RootIsNoc(t *testing.T) { require.NoError(t, err) // add x509 certificate - addX509Cert := types.NewMsgAddX509Cert(accAddress.String(), testconstants.IntermediateCertWithVid1) + addX509Cert := types.NewMsgAddX509Cert(accAddress.String(), testconstants.IntermediateCertPem) _, err = setup.Handler(setup.Ctx, addX509Cert) - require.Error(t, err) - require.True(t, pkitypes.ErrCertVidNotEqualAccountVid.Is(err)) + require.ErrorIs(t, err, pkitypes.ErrInappropriateCertificateType) } func TestHandler_AddX509Cert_ForDifferentSerialNumber(t *testing.T) { @@ -240,8 +234,7 @@ func TestHandler_AddX509Cert_ForAbsentDirectParentCert(t *testing.T) { // add intermediate x509 certificate addX509Cert := types.NewMsgAddX509Cert(vendorAccAddress.String(), testconstants.IntermediateCertPem) _, err := setup.Handler(setup.Ctx, addX509Cert) - require.Error(t, err) - require.True(t, pkitypes.ErrInvalidCertificate.Is(err)) + require.ErrorIs(t, err, pkitypes.ErrInvalidCertificate) } func TestHandler_AddX509Cert_ForFailedCertificateVerification(t *testing.T) { @@ -259,8 +252,7 @@ func TestHandler_AddX509Cert_ForFailedCertificateVerification(t *testing.T) { // add intermediate x509 certificate addX509Cert := types.NewMsgAddX509Cert(vendorAccAddress.String(), testconstants.IntermediateCertPem) _, err := setup.Handler(setup.Ctx, addX509Cert) - require.Error(t, err) - require.True(t, pkitypes.ErrInvalidCertificate.Is(err)) + require.ErrorIs(t, err, pkitypes.ErrInvalidCertificate) } func TestHandler_AddX509Cert_ForTree(t *testing.T) { @@ -435,7 +427,7 @@ func TestHandler_AddX509Cert_ByNotOwnerButSameVendor(t *testing.T) { require.NoError(t, err) } -func TestHandler_AddX509Cert_ByNotOwnerAndOtherVendor(t *testing.T) { +func TestHandler_AddX509Cert_ByOtherVendor(t *testing.T) { setup := Setup(t) // store root certificate @@ -463,11 +455,10 @@ func TestHandler_AddX509Cert_ByNotOwnerAndOtherVendor(t *testing.T) { // add an intermediate certificate with the same subject and SKID by second vendor account addX509Cert := types.NewMsgAddX509Cert(vendorAccAddress2.String(), testconstants.IntermediateCertPem) _, err := setup.Handler(setup.Ctx, addX509Cert) - require.Error(t, err) - require.True(t, sdkerrors.ErrUnauthorized.Is(err)) + require.ErrorIs(t, err, sdkerrors.ErrUnauthorized) } -func TestHandler_AddX509Cert_SendorNotVendor(t *testing.T) { +func TestHandler_AddX509Cert_SenderNotVendor(t *testing.T) { setup := Setup(t) // store root certificate @@ -477,8 +468,7 @@ func TestHandler_AddX509Cert_SendorNotVendor(t *testing.T) { // add x509 certificate addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertWithVid1) _, err := setup.Handler(setup.Ctx, addX509Cert) - require.Error(t, err) - require.True(t, sdkerrors.ErrUnauthorized.Is(err)) + require.ErrorIs(t, err, sdkerrors.ErrUnauthorized) } func TestHandler_AddX509Cert_VIDScopedRoot(t *testing.T) { @@ -569,13 +559,6 @@ func TestHandler_AddX509Cert_VIDScopedRoot_NegativeCases(t *testing.T) { accountVid int32 err error }{ - // { - // name: "NonVidScopedChild", - // rootCertOptions: createRootWithVidOptions(), - // childCert: testconstants.IntermediateCertPem, - // accountVid: testconstants.PAICertWithVidVid, - // err: pkitypes.ErrCertVidNotEqualToRootVid, - // }, { name: "IncorrectChildVid", rootCertOptions: createRootWithVidOptions(), @@ -624,7 +607,7 @@ func TestHandler_AddX509Cert_NonVIDScopedRoot_NegativeCases(t *testing.T) { rootCertOptions: createPAACertNoVidOptions(testconstants.Vid), childCert: testconstants.PAICertWithNumericVid, accountVid: testconstants.Vid, - err: pkitypes.ErrCertVidNotEqualAccountVid, + err: pkitypes.ErrCertVidNotEqualToRootVid, }, { name: "IncorrectAccountVid", diff --git a/x/pki/handler_remove_non_root_cert_test.go b/x/pki/handler_remove_non_root_cert_test.go index aaa788165..445c20bc0 100644 --- a/x/pki/handler_remove_non_root_cert_test.go +++ b/x/pki/handler_remove_non_root_cert_test.go @@ -21,20 +21,26 @@ func TestHandler_RemoveX509Cert_BySerialNumber(t *testing.T) { subject: testconstants.RootCertWithSameSubjectAndSKIDSubject, subjectKeyID: testconstants.RootCertWithSameSubjectAndSKIDSubjectKeyID, info: testconstants.Info, - vid: 65521, + vid: testconstants.RootCertWithVidVid, } proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOptions) - // Add two intermediate certificates again - addIntermediateX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateWithSameSubjectAndSKID1) + // Add vendor account + vendorAccAddress := GenerateAccAddress() + setup.AddAccount(vendorAccAddress, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.RootCertWithVidVid) + + // Add intermediate certificates + addIntermediateX509Cert := types.NewMsgAddX509Cert(vendorAccAddress.String(), testconstants.IntermediateWithSameSubjectAndSKID1) _, err := setup.Handler(setup.Ctx, addIntermediateX509Cert) require.NoError(t, err) - addIntermediateX509Cert = types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateWithSameSubjectAndSKID2) + + // Add intermediate certificates with sam subject and SKID but different serial number + addIntermediateX509Cert = types.NewMsgAddX509Cert(vendorAccAddress.String(), testconstants.IntermediateWithSameSubjectAndSKID2) _, err = setup.Handler(setup.Ctx, addIntermediateX509Cert) require.NoError(t, err) // Add a leaf certificate - addLeafX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.LeafCertWithSameSubjectAndSKID) + addLeafX509Cert := types.NewMsgAddX509Cert(vendorAccAddress.String(), testconstants.LeafCertWithSameSubjectAndSKID) _, err = setup.Handler(setup.Ctx, addLeafX509Cert) require.NoError(t, err) @@ -45,7 +51,7 @@ func TestHandler_RemoveX509Cert_BySerialNumber(t *testing.T) { // remove intermediate certificate by serial number removeX509Cert := types.NewMsgRemoveX509Cert( - setup.Trustee1.String(), + vendorAccAddress.String(), testconstants.IntermediateCertWithSameSubjectAndSKIDSubject, testconstants.IntermediateCertWithSameSubjectAndSKIDSubjectKeyID, testconstants.IntermediateCertWithSameSubjectAndSKID1SerialNumber, @@ -66,7 +72,7 @@ func TestHandler_RemoveX509Cert_BySerialNumber(t *testing.T) { // remove intermediate certificate by serial number and check that leaf cert is not removed removeX509Cert = types.NewMsgRemoveX509Cert( - setup.Trustee1.String(), + vendorAccAddress.String(), testconstants.IntermediateCertWithSameSubjectAndSKIDSubject, testconstants.IntermediateCertWithSameSubjectAndSKIDSubjectKeyID, testconstants.IntermediateCertWithSameSubjectAndSKID2SerialNumber, @@ -99,12 +105,16 @@ func TestHandler_RemoveX509Cert_RevokedAndApprovedCertificate(t *testing.T) { subject: testconstants.RootCertWithSameSubjectAndSKIDSubject, subjectKeyID: testconstants.RootCertWithSameSubjectAndSKIDSubjectKeyID, info: testconstants.Info, - vid: 65521, + vid: testconstants.RootCertWithVidVid, } proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOptions) + // Add vendor account + vendorAccAddress := GenerateAccAddress() + setup.AddAccount(vendorAccAddress, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.RootCertWithVidVid) + // Add an intermediate certificate - addIntermediateX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateWithSameSubjectAndSKID1) + addIntermediateX509Cert := types.NewMsgAddX509Cert(vendorAccAddress.String(), testconstants.IntermediateWithSameSubjectAndSKID1) _, err := setup.Handler(setup.Ctx, addIntermediateX509Cert) require.NoError(t, err) @@ -116,7 +126,7 @@ func TestHandler_RemoveX509Cert_RevokedAndApprovedCertificate(t *testing.T) { // revoke an intermediate certificate revokeX509Cert := types.NewMsgRemoveX509Cert( - setup.Trustee1.String(), + vendorAccAddress.String(), testconstants.IntermediateCertWithSameSubjectAndSKIDSubject, testconstants.IntermediateCertWithSameSubjectAndSKIDSubjectKeyID, testconstants.IntermediateCertWithSameSubjectAndSKID1SerialNumber, @@ -125,7 +135,7 @@ func TestHandler_RemoveX509Cert_RevokedAndApprovedCertificate(t *testing.T) { require.NoError(t, err) // Add an intermediate certificate with new serial number - addIntermediateX509Cert = types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateWithSameSubjectAndSKID2) + addIntermediateX509Cert = types.NewMsgAddX509Cert(vendorAccAddress.String(), testconstants.IntermediateWithSameSubjectAndSKID2) _, err = setup.Handler(setup.Ctx, addIntermediateX509Cert) require.NoError(t, err) @@ -137,7 +147,7 @@ func TestHandler_RemoveX509Cert_RevokedAndApprovedCertificate(t *testing.T) { // remove an intermediate certificate removeX509Cert := types.NewMsgRemoveX509Cert( - setup.Trustee1.String(), + vendorAccAddress.String(), testconstants.IntermediateCertWithSameSubjectAndSKIDSubject, testconstants.IntermediateCertWithSameSubjectAndSKIDSubjectKeyID, testconstants.IntermediateCertWithSameSubjectAndSKID2SerialNumber, @@ -169,12 +179,16 @@ func TestHandler_RemoveX509Cert_RevokedCertificate(t *testing.T) { subject: testconstants.RootSubject, subjectKeyID: testconstants.RootSubjectKeyID, info: testconstants.Info, - vid: 65521, + vid: testconstants.RootCertWithVidVid, } proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOptions) + // Add vendor account + vendorAccAddress := GenerateAccAddress() + setup.AddAccount(vendorAccAddress, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.RootCertWithVidVid) + // Add two intermediate certificates again - addIntermediateX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) + addIntermediateX509Cert := types.NewMsgAddX509Cert(vendorAccAddress.String(), testconstants.IntermediateCertPem) _, err := setup.Handler(setup.Ctx, addIntermediateX509Cert) require.NoError(t, err) @@ -185,7 +199,7 @@ func TestHandler_RemoveX509Cert_RevokedCertificate(t *testing.T) { // revoke intermediate certificate by serial number revokeX509Cert := types.NewMsgRevokeX509Cert( - setup.Trustee1.String(), + vendorAccAddress.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, testconstants.IntermediateSerialNumber, @@ -205,7 +219,7 @@ func TestHandler_RemoveX509Cert_RevokedCertificate(t *testing.T) { // remove intermediate certificate by serial number removeX509Cert := types.NewMsgRemoveX509Cert( - setup.Trustee1.String(), + vendorAccAddress.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, testconstants.IntermediateSerialNumber, @@ -230,8 +244,12 @@ func TestHandler_RemoveX509Cert_RevokedCertificate(t *testing.T) { func TestHandler_RemoveX509Cert_CertificateDoesNotExist(t *testing.T) { setup := Setup(t) + // Add vendor account + vendorAccAddress := GenerateAccAddress() + setup.AddAccount(vendorAccAddress, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.Vid) + removeX509Cert := types.NewMsgRemoveX509Cert( - setup.Trustee1.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, testconstants.IntermediateSerialNumber) + vendorAccAddress.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, testconstants.IntermediateSerialNumber) _, err := setup.Handler(setup.Ctx, removeX509Cert) require.Error(t, err) require.True(t, pkitypes.ErrCertificateDoesNotExist.Is(err)) @@ -243,6 +261,10 @@ func TestHandler_RemoveX509Cert_EmptyCertificatesList(t *testing.T) { rootCertificate := rootCertificate(setup.Trustee1) setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCertificate) + // Add vendor account + vendorAccAddress := GenerateAccAddress() + setup.AddAccount(vendorAccAddress, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.Vid) + setup.Keeper.SetApprovedCertificates( setup.Ctx, types.ApprovedCertificates{ @@ -252,32 +274,12 @@ func TestHandler_RemoveX509Cert_EmptyCertificatesList(t *testing.T) { ) removeX509Cert := types.NewMsgRemoveX509Cert( - setup.Trustee1.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, "") + vendorAccAddress.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, "") _, err := setup.Handler(setup.Ctx, removeX509Cert) require.Error(t, err) require.True(t, pkitypes.ErrCertificateDoesNotExist.Is(err)) } -func TestHandler_RemoveX509Cert_ByNotOwner(t *testing.T) { - setup := Setup(t) - - rootCertificate := rootCertificate(setup.Trustee1) - setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCertificate) - - addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) - _, err := setup.Handler(setup.Ctx, addX509Cert) - require.NoError(t, err) - - anotherTrustee := GenerateAccAddress() - setup.AddAccount(anotherTrustee, []dclauthtypes.AccountRole{dclauthtypes.Trustee}, 1) - - removeX509Cert := types.NewMsgRemoveX509Cert( - anotherTrustee.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, "") - _, err = setup.Handler(setup.Ctx, removeX509Cert) - require.Error(t, err) - require.True(t, sdkerrors.ErrUnauthorized.Is(err)) -} - func TestHandler_RemoveX509Cert_ByNotOwnerButSameVendor(t *testing.T) { setup := Setup(t) @@ -328,7 +330,7 @@ func TestHandler_RemoveX509Cert_ByNotOwnerButSameVendor(t *testing.T) { testconstants.IntermediateIssuer, testconstants.IntermediateSerialNumber)) } -func TestHandler_RemoveX509Cert_ByNotOwnerAndOtherVendor(t *testing.T) { +func TestHandler_RemoveX509Cert_ByOtherVendor(t *testing.T) { setup := Setup(t) // store root certificate @@ -340,7 +342,7 @@ func TestHandler_RemoveX509Cert_ByNotOwnerAndOtherVendor(t *testing.T) { setup.AddAccount(vendorAccAddress1, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.Vid) // add x509 certificate by `setup.Trustee` - addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) + addX509Cert := types.NewMsgAddX509Cert(vendorAccAddress1.String(), testconstants.IntermediateCertPem) _, err := setup.Handler(setup.Ctx, addX509Cert) require.NoError(t, err) @@ -356,14 +358,41 @@ func TestHandler_RemoveX509Cert_ByNotOwnerAndOtherVendor(t *testing.T) { require.True(t, sdkerrors.ErrUnauthorized.Is(err)) } +func TestHandler_RemoveX509Cert_SenderNotVendor(t *testing.T) { + setup := Setup(t) + + // store root certificate + rootCertOptions := createRootWithVidOptions() + proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOptions) + + // Add vendor account + vendorAccAddress := GenerateAccAddress() + setup.AddAccount(vendorAccAddress, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.RootCertWithVidVid) + + // add x509 certificate + addX509Cert := types.NewMsgAddX509Cert(vendorAccAddress.String(), testconstants.IntermediateCertWithVid1) + _, err := setup.Handler(setup.Ctx, addX509Cert) + require.NoError(t, err) + + removeX509Cert := types.NewMsgRemoveX509Cert( + setup.Trustee1.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, "invalid") + _, err = setup.Handler(setup.Ctx, removeX509Cert) + require.Error(t, err) + require.True(t, sdkerrors.ErrUnauthorized.Is(err)) +} + func TestHandler_RemoveX509Cert_ForRootCertificate(t *testing.T) { setup := Setup(t) rootCertOptions := createTestRootCertOptions() proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOptions) + // Add vendor account + vendorAccAddress := GenerateAccAddress() + setup.AddAccount(vendorAccAddress, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.Vid) + removeX509Cert := types.NewMsgRemoveX509Cert( - setup.Trustee1.String(), testconstants.RootSubject, testconstants.RootSubjectKeyID, testconstants.RootSerialNumber) + vendorAccAddress.String(), testconstants.RootSubject, testconstants.RootSubjectKeyID, testconstants.RootSerialNumber) _, err := setup.Handler(setup.Ctx, removeX509Cert) require.Error(t, err) require.True(t, pkitypes.ErrInappropriateCertificateType.Is(err)) @@ -375,12 +404,16 @@ func TestHandler_RemoveX509Cert_InvalidSerialNumber(t *testing.T) { rootCertOptions := createTestRootCertOptions() proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOptions) - addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) + // Add vendor account + vendorAccAddress := GenerateAccAddress() + setup.AddAccount(vendorAccAddress, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.Vid) + + addX509Cert := types.NewMsgAddX509Cert(vendorAccAddress.String(), testconstants.IntermediateCertPem) _, err := setup.Handler(setup.Ctx, addX509Cert) require.NoError(t, err) removeX509Cert := types.NewMsgRemoveX509Cert( - setup.Trustee1.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, "invalid") + vendorAccAddress.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, "invalid") _, err = setup.Handler(setup.Ctx, removeX509Cert) require.Error(t, err) require.True(t, pkitypes.ErrCertificateDoesNotExist.Is(err)) @@ -394,20 +427,24 @@ func TestHandler_RemoveX509Cert_BySubjectAndSKID(t *testing.T) { subject: testconstants.RootCertWithSameSubjectAndSKIDSubject, subjectKeyID: testconstants.RootCertWithSameSubjectAndSKIDSubjectKeyID, info: testconstants.Info, - vid: 65521, + vid: testconstants.RootCertWithVidVid, } proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOptions) + // Add vendor account + vendorAccAddress := GenerateAccAddress() + setup.AddAccount(vendorAccAddress, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.RootCertWithVidVid) + // Add two intermediate certificates - addIntermediateX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateWithSameSubjectAndSKID1) + addIntermediateX509Cert := types.NewMsgAddX509Cert(vendorAccAddress.String(), testconstants.IntermediateWithSameSubjectAndSKID1) _, err := setup.Handler(setup.Ctx, addIntermediateX509Cert) require.NoError(t, err) - addIntermediateX509Cert = types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateWithSameSubjectAndSKID2) + addIntermediateX509Cert = types.NewMsgAddX509Cert(vendorAccAddress.String(), testconstants.IntermediateWithSameSubjectAndSKID2) _, err = setup.Handler(setup.Ctx, addIntermediateX509Cert) require.NoError(t, err) // Add a leaf certificate - addLeafX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.LeafCertWithSameSubjectAndSKID) + addLeafX509Cert := types.NewMsgAddX509Cert(vendorAccAddress.String(), testconstants.LeafCertWithSameSubjectAndSKID) _, err = setup.Handler(setup.Ctx, addLeafX509Cert) require.NoError(t, err) @@ -419,7 +456,7 @@ func TestHandler_RemoveX509Cert_BySubjectAndSKID(t *testing.T) { // remove all intermediate certificates but leave leaf certificate removeX509Cert := types.NewMsgRemoveX509Cert( - setup.Trustee1.String(), + vendorAccAddress.String(), testconstants.IntermediateCertWithSameSubjectAndSKIDSubject, testconstants.IntermediateCertWithSameSubjectAndSKIDSubjectKeyID, "", diff --git a/x/pki/handler_revoke_non_root_cert_test.go b/x/pki/handler_revoke_non_root_cert_test.go index 9d531802c..9395210d4 100644 --- a/x/pki/handler_revoke_non_root_cert_test.go +++ b/x/pki/handler_revoke_non_root_cert_test.go @@ -13,31 +13,16 @@ import ( "google.golang.org/grpc/status" ) -func TestHandler_RevokeX509CertRoot_CertificateDoesNotExistBySerialNumber(t *testing.T) { - setup := Setup(t) - // propose and approve x509 root certificate - rootCertOptions := createTestRootCertOptions() - proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOptions) - - // revoke x509 certificate - revokeX509Cert := types.NewMsgProposeRevokeX509RootCert( - setup.Trustee1.String(), - testconstants.RootSubject, - testconstants.RootSubjectKeyID, - "invalid", - false, - testconstants.Info, - ) - _, err := setup.Handler(setup.Ctx, revokeX509Cert) - require.Error(t, err) - require.True(t, pkitypes.ErrCertificateDoesNotExist.Is(err)) -} func TestHandler_RevokeX509Cert_CertificateDoesNotExist(t *testing.T) { setup := Setup(t) + // Add vendor account + vendorAccAddress := GenerateAccAddress() + setup.AddAccount(vendorAccAddress, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.Vid) + // revoke x509 certificate revokeX509Cert := types.NewMsgRevokeX509Cert( - setup.Trustee1.String(), + vendorAccAddress.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, testconstants.IntermediateSerialNumber, @@ -55,14 +40,18 @@ func TestHandler_RevokeX509Cert_CertificateDoesNotExistBySerialNumber(t *testing rootCertOptions := createTestRootCertOptions() proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOptions) + // Add vendor account + vendorAccAddress := GenerateAccAddress() + setup.AddAccount(vendorAccAddress, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.Vid) + // Add intermediate certificate - addIntermediateX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) + addIntermediateX509Cert := types.NewMsgAddX509Cert(vendorAccAddress.String(), testconstants.IntermediateCertPem) _, err := setup.Handler(setup.Ctx, addIntermediateX509Cert) require.NoError(t, err) // revoke x509 certificate revokeX509Cert := types.NewMsgRevokeX509Cert( - setup.Trustee1.String(), + vendorAccAddress.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, "invalid", @@ -81,9 +70,13 @@ func TestHandler_RevokeX509Cert_ForRootCertificate(t *testing.T) { rootCertOptions := createTestRootCertOptions() proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOptions) + // Add vendor account + vendorAccAddress := GenerateAccAddress() + setup.AddAccount(vendorAccAddress, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.Vid) + // revoke x509 root certificate revokeX509Cert := types.NewMsgRevokeX509Cert( - setup.Trustee1.String(), + vendorAccAddress.String(), testconstants.RootSubject, testconstants.RootSubjectKeyID, testconstants.RootSerialNumber, @@ -102,13 +95,17 @@ func TestHandler_RevokeX509Cert_ForTree(t *testing.T) { rootCertOptions := createTestRootCertOptions() proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOptions) + // Add vendor account + vendorAccAddress := GenerateAccAddress() + setup.AddAccount(vendorAccAddress, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.Vid) + // add intermediate x509 certificate - addIntermediateX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) + addIntermediateX509Cert := types.NewMsgAddX509Cert(vendorAccAddress.String(), testconstants.IntermediateCertPem) _, err := setup.Handler(setup.Ctx, addIntermediateX509Cert) require.NoError(t, err) // add leaf x509 certificate - addLeafX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.LeafCertPem) + addLeafX509Cert := types.NewMsgAddX509Cert(vendorAccAddress.String(), testconstants.LeafCertPem) _, err = setup.Handler(setup.Ctx, addLeafX509Cert) require.NoError(t, err) @@ -120,17 +117,17 @@ func TestHandler_RevokeX509Cert_ForTree(t *testing.T) { // revoke x509 certificate revokeX509Cert := types.NewMsgRevokeX509Cert( - setup.Trustee1.String(), + vendorAccAddress.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, "", - false, + true, testconstants.Info, ) _, err = setup.Handler(setup.Ctx, revokeX509Cert) require.NoError(t, err) - // check that intermediate and leaf certificates have been revoked + // check that intermediate certificate has been revoked allRevokedCertificates, _ := queryAllRevokedCertificates(setup) require.Equal(t, 2, len(allRevokedCertificates)) require.Equal(t, testconstants.LeafSubject, allRevokedCertificates[0].Subject) @@ -178,36 +175,6 @@ func TestHandler_RevokeX509Cert_ForTree(t *testing.T) { require.Equal(t, codes.NotFound, status.Code(err)) } -func TestHandler_RevokeX509Cert_ByNotOwner(t *testing.T) { - setup := Setup(t) - - // store root certificate - rootCertificate := rootCertificate(setup.Trustee1) - setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCertificate) - - // add x509 certificate by `setup.Trustee` - addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) - _, err := setup.Handler(setup.Ctx, addX509Cert) - require.NoError(t, err) - - // store another account - anotherTrustee := GenerateAccAddress() - setup.AddAccount(anotherTrustee, []dclauthtypes.AccountRole{dclauthtypes.Trustee}, 1) - - // revoke x509 certificate by another account - revokeX509Cert := types.NewMsgRevokeX509Cert( - anotherTrustee.String(), - testconstants.IntermediateSubject, - testconstants.IntermediateSubjectKeyID, - testconstants.IntermediateSerialNumber, - false, - testconstants.Info, - ) - _, err = setup.Handler(setup.Ctx, revokeX509Cert) - require.Error(t, err) - require.True(t, sdkerrors.ErrUnauthorized.Is(err)) -} - func TestHandler_RevokeX509Cert_ByNotOwnerButSameVendor(t *testing.T) { setup := Setup(t) @@ -267,7 +234,7 @@ func TestHandler_RevokeX509Cert_ByNotOwnerButSameVendor(t *testing.T) { testconstants.IntermediateIssuer, testconstants.IntermediateSerialNumber)) } -func TestHandler_RevokeX509Cert_ByNotOwnerAndOtherVendor(t *testing.T) { +func TestHandler_RevokeX509Cert_ByOtherVendor(t *testing.T) { setup := Setup(t) // store root certificate @@ -279,13 +246,13 @@ func TestHandler_RevokeX509Cert_ByNotOwnerAndOtherVendor(t *testing.T) { setup.AddAccount(vendorAccAddress1, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.Vid) // add x509 certificate by first vendor account - addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) + addX509Cert := types.NewMsgAddX509Cert(vendorAccAddress1.String(), testconstants.IntermediateCertPem) _, err := setup.Handler(setup.Ctx, addX509Cert) require.NoError(t, err) // add second vendor account with VID = 1000 vendorAccAddress2 := GenerateAccAddress() - setup.AddAccount(vendorAccAddress2, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.Vid) + setup.AddAccount(vendorAccAddress2, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.VendorID1) // revoke x509 certificate by second vendor account revokeX509Cert := types.NewMsgRevokeX509Cert( @@ -301,6 +268,35 @@ func TestHandler_RevokeX509Cert_ByNotOwnerAndOtherVendor(t *testing.T) { require.True(t, sdkerrors.ErrUnauthorized.Is(err)) } +func TestHandler_RevokeX509Cert_SenderNotVendor(t *testing.T) { + setup := Setup(t) + + // store root certificate + rootCertOptions := createRootWithVidOptions() + proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOptions) + + // Add vendor account + vendorAccAddress := GenerateAccAddress() + setup.AddAccount(vendorAccAddress, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.RootCertWithVidVid) + + // add x509 certificate + addX509Cert := types.NewMsgAddX509Cert(vendorAccAddress.String(), testconstants.IntermediateCertWithVid1) + _, err := setup.Handler(setup.Ctx, addX509Cert) + require.NoError(t, err) + + removeX509Cert := types.NewMsgRevokeX509Cert( + setup.Trustee1.String(), + testconstants.IntermediateSubject, + testconstants.IntermediateSubjectKeyID, + testconstants.IntermediateSerialNumber, + false, + testconstants.Info, + ) + _, err = setup.Handler(setup.Ctx, removeX509Cert) + require.Error(t, err) + require.True(t, sdkerrors.ErrUnauthorized.Is(err)) +} + func TestHandler_RevokeX509Cert(t *testing.T) { setup := Setup(t) @@ -308,72 +304,60 @@ func TestHandler_RevokeX509Cert(t *testing.T) { rootCertificate := rootCertificate(setup.Trustee1) setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCertificate) - for _, role := range []dclauthtypes.AccountRole{ - dclauthtypes.Vendor, - dclauthtypes.CertificationCenter, - dclauthtypes.Trustee, - dclauthtypes.NodeAdmin, - } { - accAddress := GenerateAccAddress() - setup.AddAccount(accAddress, []dclauthtypes.AccountRole{role}, 1) - - // add x509 certificate - addX509Cert := types.NewMsgAddX509Cert(accAddress.String(), testconstants.IntermediateCertPem) - _, err := setup.Handler(setup.Ctx, addX509Cert) - require.NoError(t, err) - - // get intermediate certificate by subject-key-id - certsBySubjectKeyID, _ := queryAllApprovedCertificatesBySubjectKeyID(setup, testconstants.IntermediateSubjectKeyID) - require.Equal(t, 1, len(certsBySubjectKeyID)) - // get certificate for further comparison - certificateBeforeRevocation, _ := querySingleApprovedCertificate( - setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) - require.NotNil(t, certificateBeforeRevocation) - - // revoke x509 certificate - revokeX509Cert := types.NewMsgRevokeX509Cert( - accAddress.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, "", false, testconstants.Info) - _, err = setup.Handler(setup.Ctx, revokeX509Cert) - require.NoError(t, err) - - // check that intermediate certificate has been revoked - allRevokedCertificates, _ := queryAllRevokedCertificates(setup) - require.Equal(t, 1, len(allRevokedCertificates)) - require.Equal(t, testconstants.IntermediateSubject, allRevokedCertificates[0].Subject) - require.Equal(t, testconstants.IntermediateSubjectKeyID, allRevokedCertificates[0].SubjectKeyId) - require.Equal(t, 1, len(allRevokedCertificates[0].Certs)) - require.Equal(t, *certificateBeforeRevocation, *allRevokedCertificates[0].Certs[0]) - - // check that root certificate stays approved - allApprovedCertificates, _ := queryAllApprovedCertificates(setup) - require.Equal(t, 1, len(allApprovedCertificates)) - require.Equal(t, testconstants.IntermediateSubject, allRevokedCertificates[0].Subject) - require.Equal(t, testconstants.IntermediateSubjectKeyID, allRevokedCertificates[0].SubjectKeyId) - - // check that intermediate certificate removed from subject-key-id -> certs map - certsBySubjectKeyID, _ = queryAllApprovedCertificatesBySubjectKeyID(setup, testconstants.IntermediateSubjectKeyID) - require.Equal(t, 0, len(certsBySubjectKeyID)) - - // check that no proposed certificate revocations have been created - allProposedCertificateRevocations, _ := queryAllProposedCertificateRevocations(setup) - require.NoError(t, err) - require.Equal(t, 0, len(allProposedCertificateRevocations)) - - // check that child certificate identifiers list of issuer do not exist anymore - _, err = queryChildCertificates(setup, testconstants.IntermediateIssuer, testconstants.IntermediateAuthorityKeyID) - require.Error(t, err) - require.Equal(t, codes.NotFound, status.Code(err)) - - // check that unique certificate key stays registered - require.True(t, setup.Keeper.IsUniqueCertificatePresent(setup.Ctx, - testconstants.IntermediateIssuer, testconstants.IntermediateSerialNumber)) - - // cleanup for next iteration - setup.Keeper.RemoveRevokedCertificates(setup.Ctx, - testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) - setup.Keeper.RemoveUniqueCertificate(setup.Ctx, - testconstants.IntermediateIssuer, testconstants.IntermediateSerialNumber) - } + // Add vendor account + vendorAccAddress := GenerateAccAddress() + setup.AddAccount(vendorAccAddress, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.Vid) + + // add x509 certificate + addX509Cert := types.NewMsgAddX509Cert(vendorAccAddress.String(), testconstants.IntermediateCertPem) + _, err := setup.Handler(setup.Ctx, addX509Cert) + require.NoError(t, err) + + // get intermediate certificate by subject-key-id + certsBySubjectKeyID, _ := queryAllApprovedCertificatesBySubjectKeyID(setup, testconstants.IntermediateSubjectKeyID) + require.Equal(t, 1, len(certsBySubjectKeyID)) + // get certificate for further comparison + certificateBeforeRevocation, _ := querySingleApprovedCertificate( + setup, testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID) + require.NotNil(t, certificateBeforeRevocation) + + // revoke x509 certificate + revokeX509Cert := types.NewMsgRevokeX509Cert( + vendorAccAddress.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, "", false, testconstants.Info) + _, err = setup.Handler(setup.Ctx, revokeX509Cert) + require.NoError(t, err) + + // check that intermediate certificate has been revoked + allRevokedCertificates, _ := queryAllRevokedCertificates(setup) + require.Equal(t, 1, len(allRevokedCertificates)) + require.Equal(t, testconstants.IntermediateSubject, allRevokedCertificates[0].Subject) + require.Equal(t, testconstants.IntermediateSubjectKeyID, allRevokedCertificates[0].SubjectKeyId) + require.Equal(t, 1, len(allRevokedCertificates[0].Certs)) + require.Equal(t, *certificateBeforeRevocation, *allRevokedCertificates[0].Certs[0]) + + // check that root certificate stays approved + allApprovedCertificates, _ := queryAllApprovedCertificates(setup) + require.Equal(t, 1, len(allApprovedCertificates)) + require.Equal(t, testconstants.IntermediateSubject, allRevokedCertificates[0].Subject) + require.Equal(t, testconstants.IntermediateSubjectKeyID, allRevokedCertificates[0].SubjectKeyId) + + // check that intermediate certificate removed from subject-key-id -> certs map + certsBySubjectKeyID, _ = queryAllApprovedCertificatesBySubjectKeyID(setup, testconstants.IntermediateSubjectKeyID) + require.Equal(t, 0, len(certsBySubjectKeyID)) + + // check that no proposed certificate revocations have been created + allProposedCertificateRevocations, _ := queryAllProposedCertificateRevocations(setup) + require.NoError(t, err) + require.Equal(t, 0, len(allProposedCertificateRevocations)) + + // check that child certificate identifiers list of issuer do not exist anymore + _, err = queryChildCertificates(setup, testconstants.IntermediateIssuer, testconstants.IntermediateAuthorityKeyID) + require.Error(t, err) + require.Equal(t, codes.NotFound, status.Code(err)) + + // check that unique certificate key stays registered + require.True(t, setup.Keeper.IsUniqueCertificatePresent(setup.Ctx, + testconstants.IntermediateIssuer, testconstants.IntermediateSerialNumber)) } func TestHandler_RevokeX509Cert_BySerialNumber(t *testing.T) { @@ -382,11 +366,15 @@ func TestHandler_RevokeX509Cert_BySerialNumber(t *testing.T) { rootCertOptions := createTestRootCertOptions() proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOptions) + // Add vendor account + vendorAccAddress := GenerateAccAddress() + setup.AddAccount(vendorAccAddress, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.Vid) + // Add two intermediate certificates - addIntermediateX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) + addIntermediateX509Cert := types.NewMsgAddX509Cert(vendorAccAddress.String(), testconstants.IntermediateCertPem) _, err := setup.Handler(setup.Ctx, addIntermediateX509Cert) require.NoError(t, err) - intermediateCertificate := intermediateCertificate(setup.Trustee1) + intermediateCertificate := intermediateCertificate(vendorAccAddress) intermediateCertificate.SerialNumber = SerialNumber setup.Keeper.AddApprovedCertificate(setup.Ctx, intermediateCertificate) setup.Keeper.AddApprovedCertificateBySubjectKeyID(setup.Ctx, intermediateCertificate) @@ -395,7 +383,7 @@ func TestHandler_RevokeX509Cert_BySerialNumber(t *testing.T) { uniqueCertificate(intermediateCertificate.Issuer, intermediateCertificate.SerialNumber), ) // Add a leaf certificate - addLeafX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.LeafCertPem) + addLeafX509Cert := types.NewMsgAddX509Cert(vendorAccAddress.String(), testconstants.LeafCertPem) _, err = setup.Handler(setup.Ctx, addLeafX509Cert) require.NoError(t, err) @@ -407,7 +395,7 @@ func TestHandler_RevokeX509Cert_BySerialNumber(t *testing.T) { // revoke only an intermediate certificate revokeX509Cert := types.NewMsgRevokeX509Cert( - setup.Trustee1.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, testconstants.IntermediateSerialNumber, false, testconstants.Info) + vendorAccAddress.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, testconstants.IntermediateSerialNumber, false, testconstants.Info) _, err = setup.Handler(setup.Ctx, revokeX509Cert) require.NoError(t, err) @@ -436,7 +424,7 @@ func TestHandler_RevokeX509Cert_BySerialNumber(t *testing.T) { // revoke intermediate and leaf certificates revokeX509Cert = types.NewMsgRevokeX509Cert( - setup.Trustee1.String(), + vendorAccAddress.String(), testconstants.IntermediateSubject, testconstants.IntermediateSubjectKeyID, SerialNumber, diff --git a/x/pki/handler_test.go b/x/pki/handler_test.go index 93ede9a48..aa4023800 100644 --- a/x/pki/handler_test.go +++ b/x/pki/handler_test.go @@ -817,6 +817,26 @@ func TestHandler_ProposeRevokeX509RootCert_CertificateDoesNotExist(t *testing.T) require.True(t, pkitypes.ErrCertificateDoesNotExist.Is(err)) } +func TestHandler_ProposeRevokeX509RootCert_CertificateDoesNotExistBySerialNumber(t *testing.T) { + setup := Setup(t) + // propose and approve x509 root certificate + rootCertOptions := createTestRootCertOptions() + proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOptions) + + // revoke x509 certificate + revokeX509Cert := types.NewMsgProposeRevokeX509RootCert( + setup.Trustee1.String(), + testconstants.RootSubject, + testconstants.RootSubjectKeyID, + "invalid", + false, + testconstants.Info, + ) + _, err := setup.Handler(setup.Ctx, revokeX509Cert) + require.Error(t, err) + require.True(t, pkitypes.ErrCertificateDoesNotExist.Is(err)) +} + func TestHandler_ProposeRevokeX509RootCert_ForProposedCertificate(t *testing.T) { setup := Setup(t) @@ -869,8 +889,12 @@ func TestHandler_ProposeRevokeX509RootCert_ForNonRootCertificate(t *testing.T) { rootCertificate := rootCertificate(setup.Trustee1) setup.Keeper.AddApprovedCertificate(setup.Ctx, rootCertificate) + // Add vendor account + vendorAccAddress := GenerateAccAddress() + setup.AddAccount(vendorAccAddress, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.Vid) + // store x509 intermediate certificate - addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) + addX509Cert := types.NewMsgAddX509Cert(vendorAccAddress.String(), testconstants.IntermediateCertPem) _, err := setup.Handler(setup.Ctx, addX509Cert) require.NoError(t, err) @@ -983,10 +1007,16 @@ func TestHandler_ApproveRevokeX509RootCert_BySerialNumber(t *testing.T) { proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOpt) rootSubject := rootCertOpt.subject rootSubjectKeyID := rootCertOpt.subjectKeyID + + // Add vendor account + vendorAccAddress := GenerateAccAddress() + setup.AddAccount(vendorAccAddress, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.Vid) + // Add an intermediate certificate - addIntermediateX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateWithSameSubjectAndSKID1) + addIntermediateX509Cert := types.NewMsgAddX509Cert(vendorAccAddress.String(), testconstants.IntermediateWithSameSubjectAndSKID1) _, err := setup.Handler(setup.Ctx, addIntermediateX509Cert) require.NoError(t, err) + intermediateSubject := testconstants.IntermediateCertWithSameSubjectAndSKIDSubject intermediateSubjectKeyID := testconstants.IntermediateCertWithSameSubjectAndSKIDSubjectKeyID @@ -1138,13 +1168,18 @@ func TestHandler_ApproveRevokeX509RootCert_ForTree(t *testing.T) { // add root x509 certificate rootCertOptions := createTestRootCertOptions() proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOptions) + + // Add vendor account + vendorAccAddress := GenerateAccAddress() + setup.AddAccount(vendorAccAddress, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.Vid) + // add intermediate x509 certificate - addIntermediateX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) + addIntermediateX509Cert := types.NewMsgAddX509Cert(vendorAccAddress.String(), testconstants.IntermediateCertPem) _, err := setup.Handler(setup.Ctx, addIntermediateX509Cert) require.NoError(t, err) // add leaf x509 certificate - addLeafX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.LeafCertPem) + addLeafX509Cert := types.NewMsgAddX509Cert(vendorAccAddress.String(), testconstants.LeafCertPem) _, err = setup.Handler(setup.Ctx, addLeafX509Cert) require.NoError(t, err) @@ -1825,8 +1860,12 @@ func TestHandler_AssignVid_ForNonRootCertificate(t *testing.T) { rootCertOptions := createTestRootCertOptions() proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOptions) + // Add vendor account + vendorAccAddress := GenerateAccAddress() + setup.AddAccount(vendorAccAddress, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.Vid) + // add x509 intermediate certificate - addX509Cert := types.NewMsgAddX509Cert(setup.Trustee1.String(), testconstants.IntermediateCertPem) + addX509Cert := types.NewMsgAddX509Cert(vendorAccAddress.String(), testconstants.IntermediateCertPem) _, err := setup.Handler(setup.Ctx, addX509Cert) require.NoError(t, err) diff --git a/x/pki/keeper/msg_server_add_x_509_cert.go b/x/pki/keeper/msg_server_add_x_509_cert.go index fde211288..1ab8947a6 100644 --- a/x/pki/keeper/msg_server_add_x_509_cert.go +++ b/x/pki/keeper/msg_server_add_x_509_cert.go @@ -78,10 +78,13 @@ func (k msgServer) AddX509Cert(goCtx context.Context, msg *types.MsgAddX509Cert) // Root certificate must not be NOC if rootCert.IsNoc { - return nil, pkitypes.NewErrProvidedNotNocCertButExistingNoc(x509Certificate.Subject, x509Certificate.SubjectKeyID) + return nil, pkitypes.NewErrProvidedNotNocCertButRootNoc() } - k.ensureCertsAndSenderVidMatch(ctx, rootCert, x509Certificate, signerAddr) + // Provided certificate, root certificate and account VID must match + if err = k.ensureCertsAndSenderVidMatch(ctx, rootCert, x509Certificate, signerAddr); err != nil { + return nil, err + } // create new certificate certificate := types.NewNonRootCertificate( @@ -157,8 +160,8 @@ func (k msgServer) ensureCertsAndSenderVidMatch( } else { // If added under a non-VID scoped root CA: // Child certificate must be either VID scoped to the same VID, or non-VID scoped. - if childVid != 0 && childVid != accountVID { - return pkitypes.NewErrCertVidNotEqualToAccountVid(accountVID, childVid) + if childVid != 0 && childVid != rootCert.Vid { + return pkitypes.NewErrRootCertVidNotEqualToCertVid(accountVID, childVid) } // Only a Vendor associated with root certificate VID can add an intermediate certificate. From 88ff7fc29b22825a545c7b6d6cb0d050969d46ac Mon Sep 17 00:00:00 2001 From: "aziz.karabashov" Date: Tue, 5 Mar 2024 17:02:55 +0500 Subject: [PATCH 05/14] Fix integration tests --- .../cli/pki-add-vendor-x509-certificates.sh | 4 +-- integration_tests/cli/pki-demo.sh | 26 ++++++++++++--- .../cli/pki-remove-x509-certificates.sh | 32 ++++++++++++++----- .../cli/pki-revocation-with-revoking-child.sh | 22 +++++++------ .../cli/pki-revocation-with-serial-number.sh | 26 ++++++++------- types/pki/errors.go | 9 +----- x/pki/keeper/msg_server_add_x_509_cert.go | 2 +- 7 files changed, 77 insertions(+), 44 deletions(-) diff --git a/integration_tests/cli/pki-add-vendor-x509-certificates.sh b/integration_tests/cli/pki-add-vendor-x509-certificates.sh index 3927a2751..d7fec4ca9 100755 --- a/integration_tests/cli/pki-add-vendor-x509-certificates.sh +++ b/integration_tests/cli/pki-add-vendor-x509-certificates.sh @@ -165,8 +165,8 @@ echo "Create Vendor account - $second_vendor_account_65521" create_new_vendor_account $second_vendor_account_65521 $vendor_vid_65521 echo "Add second intermediate certificate with same subject and SKID by $second_vendor_account_65521" -result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$intermediate_cert_2_path" --from $vendor_account_65523 --yes) -check_response "$result" "\"code\": 4" +result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$intermediate_cert_2_path" --from $vendor_account_65521 --yes) +check_response "$result" "\"code\": 0" echo "Request all approved root certificates should contain intermediate cert with serialNumber=$intermediate_cert_2_serial_number" result=$(dcld query pki all-x509-certs) diff --git a/integration_tests/cli/pki-demo.sh b/integration_tests/cli/pki-demo.sh index 4798f7043..893af44a4 100755 --- a/integration_tests/cli/pki-demo.sh +++ b/integration_tests/cli/pki-demo.sh @@ -43,6 +43,14 @@ trustee_account_address=$(echo $passphrase | dcld keys show jack -a) second_trustee_account_address=$(echo $passphrase | dcld keys show alice -a) third_trustee_account_address=$(echo $passphrase | dcld keys show bob -a) +vendor_account=vendor_account_$vid +echo "Create Vendor account - $vendor_account" +create_new_vendor_account $vendor_account $vid + +vendor_account_65522=vendor_account_65522 +echo "Create Vendor account - $vendor_account_65522" +create_new_vendor_account $vendor_account_65522 65522 + echo "Create regular account" create_new_account user_account "CertificationCenter" test_divider @@ -374,9 +382,9 @@ echo "4. ADD INTERMEDIATE CERT" test_divider -echo "$user_account (Not Trustee) adds Intermediate certificate" +echo "$vendor_account adds Intermediate certificate" intermediate_path="integration_tests/constants/intermediate_cert" -result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$intermediate_path" --from $user_account --yes) +result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$intermediate_path" --from $vendor_account --yes) check_response "$result" "\"code\": 0" @@ -442,9 +450,9 @@ test_divider echo "5. ADD LEAF CERT" test_divider -echo "$trustee_account (Trustee) add Leaf certificate" +echo "$vendor_account add Leaf certificate" leaf_path="integration_tests/constants/leaf_cert" -result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$leaf_path" --from $trustee_account --yes) +result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$leaf_path" --from $vendor_account --yes) check_response "$result" "\"code\": 0" test_divider @@ -650,8 +658,16 @@ test_divider echo "6. REVOKE INTERMEDIATE (AND HENCE LEAF) CERTS - No Approvals needed" test_divider -echo "$user_account (Not Trustee) revokes only Intermediate certificate. This must not revoke its child - Leaf certificate." +echo "Try to revoke the intermediate certificate using an account that does not have vendor role" result=$(echo "$passphrase" | dcld tx pki revoke-x509-cert --subject="$intermediate_cert_subject" --subject-key-id="$intermediate_cert_subject_key_id" --from=$user_account --yes) +check_response "$result" "\"code\": 4" + +echo "Try to revoke the intermediate certificate using a vendor account with other VID" +result=$(echo "$passphrase" | dcld tx pki revoke-x509-cert --subject="$intermediate_cert_subject" --subject-key-id="$intermediate_cert_subject_key_id" --from=$vendor_account_65522 --yes) +check_response "$result" "\"code\": 4" + +echo "$vendor_account (Not Trustee) revokes only Intermediate certificate. This must not revoke its child - Leaf certificate." +result=$(echo "$passphrase" | dcld tx pki revoke-x509-cert --subject="$intermediate_cert_subject" --subject-key-id="$intermediate_cert_subject_key_id" --from=$vendor_account --yes) check_response "$result" "\"code\": 0" test_divider diff --git a/integration_tests/cli/pki-remove-x509-certificates.sh b/integration_tests/cli/pki-remove-x509-certificates.sh index 3206ab46c..209c7f033 100755 --- a/integration_tests/cli/pki-remove-x509-certificates.sh +++ b/integration_tests/cli/pki-remove-x509-certificates.sh @@ -24,6 +24,14 @@ test_divider echo "REMOVE X509 CERTIFICATES" +vendor_account_65521=vendor_account_$root_cert_vid +echo "Create Vendor account - $vendor_account_65521" +create_new_vendor_account $vendor_account_65521 $root_cert_vid + +vendor_account_65522=vendor_account_65522 +echo "Create Vendor account - $vendor_account_65522" +create_new_vendor_account $vendor_account_65522 65522 + echo "Propose and approve root certificate 1" result=$(echo "$passphrase" | dcld tx pki propose-add-x509-root-cert --certificate="$root_cert_1_path" --vid "$root_cert_vid" --from $trustee_account --yes) check_response "$result" "\"code\": 0" @@ -31,15 +39,15 @@ result=$(echo "$passphrase" | dcld tx pki approve-add-x509-root-cert --subject=" check_response "$result" "\"code\": 0" echo "Add an intermediate certificate with serialNumber 3" -result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$intermediate_cert_1_path" --from $trustee_account --yes) +result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$intermediate_cert_1_path" --from $vendor_account_65521 --yes) check_response "$result" "\"code\": 0" echo "Add an intermediate certificate with serialNumber 4" -result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$intermediate_cert_2_path" --from $trustee_account --yes) +result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$intermediate_cert_2_path" --from $vendor_account_65521 --yes) check_response "$result" "\"code\": 0" echo "Add a leaf certificate with serialNumber 5" -result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$leaf_cert_path" --from $trustee_account --yes) +result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$leaf_cert_path" --from $vendor_account_65521 --yes) check_response "$result" "\"code\": 0" echo "Request all approved root certificates." @@ -56,7 +64,7 @@ check_response "$result" "\"serialNumber\": \"$intermediate_cert_2_serial_number check_response "$result" "\"serialNumber\": \"$leaf_cert_serial_number\"" echo "Revoke an intermediate certificate with serialNumber 3" -result=$(echo "$passphrase" | dcld tx pki revoke-x509-cert --subject="$intermediate_cert_subject" --subject-key-id="$intermediate_cert_subject_key_id" --serial-number="$intermediate_cert_1_serial_number" --from=$trustee_account --yes) +result=$(echo "$passphrase" | dcld tx pki revoke-x509-cert --subject="$intermediate_cert_subject" --subject-key-id="$intermediate_cert_subject_key_id" --serial-number="$intermediate_cert_1_serial_number" --from=$vendor_account_65521 --yes) check_response "$result" "\"code\": 0" echo "Request all revoked certificates should contain only one intermediate certificate with serialNumber 3" @@ -68,11 +76,19 @@ check_response "$result" "\"serialNumber\": \"$intermediate_cert_1_serial_number response_does_not_contain "$result" "\"serialNumber\": \"$intermediate_cert_2_serial_number\"" echo "Remove intermediate certificate with invalid serialNumber" -result=$(echo "$passphrase" | dcld tx pki remove-x509-cert --subject="$intermediate_cert_subject" --subject-key-id="$intermediate_cert_subject_key_id" --serial-number="invalid" --from=$trustee_account --yes) +result=$(echo "$passphrase" | dcld tx pki remove-x509-cert --subject="$intermediate_cert_subject" --subject-key-id="$intermediate_cert_subject_key_id" --serial-number="invalid" --from=$vendor_account_65521 --yes) check_response "$result" "\"code\": 404" -echo "Remove intermediate certificate with serialNumber 3" +echo "Try to remove the intermediate certificate using an account that does not have vendor role" result=$(echo "$passphrase" | dcld tx pki remove-x509-cert --subject="$intermediate_cert_subject" --subject-key-id="$intermediate_cert_subject_key_id" --serial-number="$intermediate_cert_1_serial_number" --from=$trustee_account --yes) +check_response "$result" "\"code\": 4" + +echo "Try to remove the intermediate certificate using a vendor account with other VID" +result=$(echo "$passphrase" | dcld tx pki remove-x509-cert --subject="$intermediate_cert_subject" --subject-key-id="$intermediate_cert_subject_key_id" --serial-number="$intermediate_cert_1_serial_number" --from=$vendor_account_65522 --yes) +check_response "$result" "\"code\": 4" + +echo "Remove intermediate certificate with serialNumber 3" +result=$(echo "$passphrase" | dcld tx pki remove-x509-cert --subject="$intermediate_cert_subject" --subject-key-id="$intermediate_cert_subject_key_id" --serial-number="$intermediate_cert_1_serial_number" --from=$vendor_account_65521 --yes) check_response "$result" "\"code\": 0" echo "Request all certificates should not contain intermediate certificate with serialNumber 3" @@ -97,7 +113,7 @@ check_response "$result" "\"serialNumber\": \"$intermediate_cert_2_serial_number response_does_not_contain "$result" "\"serialNumber\": \"$intermediate_cert_1_serial_number\"" echo "Remove an intermediate certificate with subject and subjectKeyId" -result=$(echo "$passphrase" | dcld tx pki remove-x509-cert --subject="$intermediate_cert_subject" --subject-key-id="$intermediate_cert_subject_key_id" --from=$trustee_account --yes) +result=$(echo "$passphrase" | dcld tx pki remove-x509-cert --subject="$intermediate_cert_subject" --subject-key-id="$intermediate_cert_subject_key_id" --from=$vendor_account_65521 --yes) check_response "$result" "\"code\": 0" echo "Request approved certificates by an intermediate certificate's subject and subjectKeyId should be empty" @@ -130,7 +146,7 @@ response_does_not_contain "$result" "\"serialNumber\": \"$intermediate_cert_2_se response_does_not_contain "$result" "\"serialNumber\": \"$intermediate_cert_1_serial_number\"" echo "Remove leaf certificate" -result=$(echo "$passphrase" | dcld tx pki remove-x509-cert --subject="$leaf_cert_subject" --subject-key-id="$leaf_cert_subject_key_id" --from=$trustee_account --yes) +result=$(echo "$passphrase" | dcld tx pki remove-x509-cert --subject="$leaf_cert_subject" --subject-key-id="$leaf_cert_subject_key_id" --from=$vendor_account_65521 --yes) check_response "$result" "\"code\": 0" echo "Request approved leaf certificates should be empty" diff --git a/integration_tests/cli/pki-revocation-with-revoking-child.sh b/integration_tests/cli/pki-revocation-with-revoking-child.sh index e1b1ed673..5a816b200 100755 --- a/integration_tests/cli/pki-revocation-with-revoking-child.sh +++ b/integration_tests/cli/pki-revocation-with-revoking-child.sh @@ -26,6 +26,10 @@ test_divider echo "REVOKE CERTIFICATES BY SPECIFYING SERIAL NUMBER" +vendor_account=vendor_account_$root_cert_vid +echo "Create Vendor account - $vendor_account" +create_new_vendor_account $vendor_account $root_cert_vid + echo "Propose and approve root certificate 1" result=$(echo "$passphrase" | dcld tx pki propose-add-x509-root-cert --certificate="$root_cert_1_path" --vid "$root_cert_vid" --from $trustee_account --yes) check_response "$result" "\"code\": 0" @@ -39,15 +43,15 @@ result=$(echo "$passphrase" | dcld tx pki approve-add-x509-root-cert --subject=" check_response "$result" "\"code\": 0" echo "Add an intermediate certificate with serialNumber 3" -result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$intermediate_cert_1_path" --from $trustee_account --yes) +result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$intermediate_cert_1_path" --from $vendor_account --yes) check_response "$result" "\"code\": 0" echo "Add an intermediate certificate with serialNumber 4" -result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$intermediate_cert_2_path" --from $trustee_account --yes) +result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$intermediate_cert_2_path" --from $vendor_account --yes) check_response "$result" "\"code\": 0" echo "Add a leaf certificate with serialNumber 5" -result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$leaf_cert_path" --from $trustee_account --yes) +result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$leaf_cert_path" --from $vendor_account --yes) check_response "$result" "\"code\": 0" echo "Request all approved root certificates." @@ -60,7 +64,7 @@ check_response "$result" "\"subjectKeyId\": \"$intermediate_cert_subject_key_id\ check_response "$result" "\"subjectKeyId\": \"$leaf_cert_subject_key_id\"" echo "Revoke intermediate certificates and its child certificates too" -result=$(echo "$passphrase" | dcld tx pki revoke-x509-cert --subject="$intermediate_cert_subject" --subject-key-id="$intermediate_cert_subject_key_id" --revoke-child=true --from=$trustee_account --yes) +result=$(echo "$passphrase" | dcld tx pki revoke-x509-cert --subject="$intermediate_cert_subject" --subject-key-id="$intermediate_cert_subject_key_id" --revoke-child=true --from=$vendor_account --yes) check_response "$result" "\"code\": 0" echo "Request all revoked certificates should contain two intermediate and one leaf certificates" @@ -88,21 +92,21 @@ response_does_not_contain "$result" "\"serialNumber\": \"$intermediate_cert_2_se response_does_not_contain "$result" "\"serialNumber\": \"$leaf_cert_serial_number" echo "Remove intermediate and leaf certificates to re-add them again" -result=$(echo "$passphrase" | dcld tx pki remove-x509-cert --subject="$intermediate_cert_subject" --subject-key-id="$intermediate_cert_subject_key_id" --from=$trustee_account --yes) +result=$(echo "$passphrase" | dcld tx pki remove-x509-cert --subject="$intermediate_cert_subject" --subject-key-id="$intermediate_cert_subject_key_id" --from=$vendor_account --yes) check_response "$result" "\"code\": 0" -result=$(echo "$passphrase" | dcld tx pki remove-x509-cert --subject="$leaf_cert_subject" --subject-key-id="$leaf_cert_subject_key_id" --from=$trustee_account --yes) +result=$(echo "$passphrase" | dcld tx pki remove-x509-cert --subject="$leaf_cert_subject" --subject-key-id="$leaf_cert_subject_key_id" --from=$vendor_account --yes) check_response "$result" "\"code\": 0" echo "Add an intermediate certificate with serialNumber 3" -result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$intermediate_cert_1_path" --from $trustee_account --yes) +result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$intermediate_cert_1_path" --from $vendor_account --yes) check_response "$result" "\"code\": 0" echo "Add an intermediate certificate with serialNumber 4" -result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$intermediate_cert_2_path" --from $trustee_account --yes) +result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$intermediate_cert_2_path" --from $vendor_account --yes) check_response "$result" "\"code\": 0" echo "Add a leaf certificate with serialNumber 5" -result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$leaf_cert_path" --from $trustee_account --yes) +result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$leaf_cert_path" --from $vendor_account --yes) check_response "$result" "\"code\": 0" echo "$trustee_account (Trustee) proposes to revoke Root certificates and its child certificates too" diff --git a/integration_tests/cli/pki-revocation-with-serial-number.sh b/integration_tests/cli/pki-revocation-with-serial-number.sh index 6eed1f244..243666ece 100755 --- a/integration_tests/cli/pki-revocation-with-serial-number.sh +++ b/integration_tests/cli/pki-revocation-with-serial-number.sh @@ -26,6 +26,10 @@ test_divider echo "REVOKE CERTIFICATES BY SPECIFYING SERIAL NUMBER" +vendor_account=vendor_account_$root_cert_vid +echo "Create Vendor account - $vendor_account" +create_new_vendor_account $vendor_account $root_cert_vid + echo "Propose and approve root certificate 1" result=$(echo "$passphrase" | dcld tx pki propose-add-x509-root-cert --certificate="$root_cert_1_path" --vid "$root_cert_vid" --from $trustee_account --yes) check_response "$result" "\"code\": 0" @@ -39,15 +43,15 @@ result=$(echo "$passphrase" | dcld tx pki approve-add-x509-root-cert --subject=" check_response "$result" "\"code\": 0" echo "Add an intermediate certificate with serialNumber 3" -result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$intermediate_cert_1_path" --from $trustee_account --yes) +result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$intermediate_cert_1_path" --from $vendor_account --yes) check_response "$result" "\"code\": 0" echo "Add an intermediate certificate with serialNumber 4" -result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$intermediate_cert_2_path" --from $trustee_account --yes) +result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$intermediate_cert_2_path" --from $vendor_account --yes) check_response "$result" "\"code\": 0" echo "Add a leaf certificate with serialNumber 5" -result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$leaf_cert_path" --from $trustee_account --yes) +result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$leaf_cert_path" --from $vendor_account --yes) check_response "$result" "\"code\": 0" echo "Request all approved root certificates." @@ -65,11 +69,11 @@ check_response "$result" "\"serialNumber\": \"$intermediate_cert_2_serial_number check_response "$result" "\"serialNumber\": \"$leaf_cert_serial_number\"" echo "Revoke intermediate certificate with invalid serialNumber" -result=$(echo "$passphrase" | dcld tx pki revoke-x509-cert --subject="$intermediate_cert_subject" --subject-key-id="$intermediate_cert_subject_key_id" --serial-number="invalid" --from=$trustee_account --yes) +result=$(echo "$passphrase" | dcld tx pki revoke-x509-cert --subject="$intermediate_cert_subject" --subject-key-id="$intermediate_cert_subject_key_id" --serial-number="invalid" --from=$vendor_account --yes) check_response "$result" "\"code\": 404" echo "Revoke intermediate certificate with serialNumber 3 only(child certificates should not be removed)" -result=$(echo "$passphrase" | dcld tx pki revoke-x509-cert --subject="$intermediate_cert_subject" --subject-key-id="$intermediate_cert_subject_key_id" --serial-number="$intermediate_cert_1_serial_number" --from=$trustee_account --yes) +result=$(echo "$passphrase" | dcld tx pki revoke-x509-cert --subject="$intermediate_cert_subject" --subject-key-id="$intermediate_cert_subject_key_id" --serial-number="$intermediate_cert_1_serial_number" --from=$vendor_account --yes) check_response "$result" "\"code\": 0" echo "Request all revoked certificates should contain one intermediate certificate with serialNumber 3" @@ -97,7 +101,7 @@ check_response "$result" "\"subjectKeyId\": \"$leaf_cert_subject_key_id\"" check_response "$result" "\"serialNumber\": \"$leaf_cert_serial_number\"" echo "Revoke intermediate certificate with serialNumber 4 and its child certificates too" -result=$(echo "$passphrase" | dcld tx pki revoke-x509-cert --subject="$intermediate_cert_subject" --subject-key-id="$intermediate_cert_subject_key_id" --serial-number="$intermediate_cert_2_serial_number" --revoke-child=true --from=$trustee_account --yes) +result=$(echo "$passphrase" | dcld tx pki revoke-x509-cert --subject="$intermediate_cert_subject" --subject-key-id="$intermediate_cert_subject_key_id" --serial-number="$intermediate_cert_2_serial_number" --revoke-child=true --from=$vendor_account --yes) check_response "$result" "\"code\": 0" echo "Request all revoked certificates should contain two intermediate and one leaf certificates" @@ -125,21 +129,21 @@ response_does_not_contain "$result" "\"serialNumber\": \"$intermediate_cert_2_se response_does_not_contain "$result" "\"serialNumber\": \"$leaf_cert_serial_number" echo "Remove intermediate and leaf certificates to re-add them again" -result=$(echo "$passphrase" | dcld tx pki remove-x509-cert --subject="$intermediate_cert_subject" --subject-key-id="$intermediate_cert_subject_key_id" --from=$trustee_account --yes) +result=$(echo "$passphrase" | dcld tx pki remove-x509-cert --subject="$intermediate_cert_subject" --subject-key-id="$intermediate_cert_subject_key_id" --from=$vendor_account --yes) check_response "$result" "\"code\": 0" -result=$(echo "$passphrase" | dcld tx pki remove-x509-cert --subject="$leaf_cert_subject" --subject-key-id="$leaf_cert_subject_key_id" --from=$trustee_account --yes) +result=$(echo "$passphrase" | dcld tx pki remove-x509-cert --subject="$leaf_cert_subject" --subject-key-id="$leaf_cert_subject_key_id" --from=$vendor_account --yes) check_response "$result" "\"code\": 0" echo "Add an intermediate certificate with serialNumber 3" -result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$intermediate_cert_1_path" --from $trustee_account --yes) +result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$intermediate_cert_1_path" --from $vendor_account --yes) check_response "$result" "\"code\": 0" echo "Add an intermediate certificate with serialNumber 4" -result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$intermediate_cert_2_path" --from $trustee_account --yes) +result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$intermediate_cert_2_path" --from $vendor_account --yes) check_response "$result" "\"code\": 0" echo "Add a leaf certificate with serialNumber 5" -result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$leaf_cert_path" --from $trustee_account --yes) +result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$leaf_cert_path" --from $vendor_account --yes) check_response "$result" "\"code\": 0" echo "Request all approved root certificates." diff --git a/types/pki/errors.go b/types/pki/errors.go index 5fbe2462c..312eac9be 100644 --- a/types/pki/errors.go +++ b/types/pki/errors.go @@ -207,7 +207,7 @@ func NewErrProvidedNotNocCertButExistingNoc(subject string, subjectKeyID string) subject, subjectKeyID) } -func NewErrProvidedNotNocCertButRootNoc() error { +func NewErrProvidedNotNocCertButRootIsNoc() error { return sdkerrors.Wrapf(ErrInappropriateCertificateType, "The root is NOC certificate, but the provided certificate is not") } @@ -225,13 +225,6 @@ func NewErrRootCertVidNotEqualToAccountVid(rootVID int32, accountVID int32) erro rootVID, accountVID) } -func NewErrCertVidNotEqualToAccountVid(accountVID int32, certVID int32) error { - return sdkerrors.Wrapf(ErrCertVidNotEqualAccountVid, - "Certificate is VID scoped: Only a vendor associated with this VID can add this certificate "+ - "Account VID = %v, Certificate's VID = %v", - accountVID, certVID) -} - func NewErrCRLSignerCertificatePidNotEqualMsgPid(certificatePid int32, messagePid int32) error { return sdkerrors.Wrapf( ErrCRLSignerCertificatePidNotEqualMsgPid, diff --git a/x/pki/keeper/msg_server_add_x_509_cert.go b/x/pki/keeper/msg_server_add_x_509_cert.go index 1ab8947a6..b0b9e6fb1 100644 --- a/x/pki/keeper/msg_server_add_x_509_cert.go +++ b/x/pki/keeper/msg_server_add_x_509_cert.go @@ -78,7 +78,7 @@ func (k msgServer) AddX509Cert(goCtx context.Context, msg *types.MsgAddX509Cert) // Root certificate must not be NOC if rootCert.IsNoc { - return nil, pkitypes.NewErrProvidedNotNocCertButRootNoc() + return nil, pkitypes.NewErrProvidedNotNocCertButRootIsNoc() } // Provided certificate, root certificate and account VID must match From b0be851c04f8d4224d09ede25759708b14f8a9a9 Mon Sep 17 00:00:00 2001 From: "aziz.karabashov" Date: Tue, 5 Mar 2024 20:25:55 +0500 Subject: [PATCH 06/14] Change signer to Vendor for non-root certificate gRPC/REST tests --- integration_tests/grpc_rest/pki/helpers.go | 78 +++++++++++----------- 1 file changed, 38 insertions(+), 40 deletions(-) diff --git a/integration_tests/grpc_rest/pki/helpers.go b/integration_tests/grpc_rest/pki/helpers.go index e3defa51f..bb1e8aed3 100644 --- a/integration_tests/grpc_rest/pki/helpers.go +++ b/integration_tests/grpc_rest/pki/helpers.go @@ -21,7 +21,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" - tmrand "github.com/tendermint/tendermint/libs/rand" testconstants "github.com/zigbee-alliance/distributed-compliance-ledger/integration_tests/constants" test_dclauth "github.com/zigbee-alliance/distributed-compliance-ledger/integration_tests/grpc_rest/dclauth" "github.com/zigbee-alliance/distributed-compliance-ledger/integration_tests/utils" @@ -650,13 +649,12 @@ func Demo(suite *utils.TestSuite) { require.NoError(suite.T, err) // Register new Vendor account - vid := int32(tmrand.Uint16()) vendorName := utils.RandString() vendorAccount := test_dclauth.CreateVendorAccount( suite, vendorName, dclauthtypes.AccountRoles{dclauthtypes.Vendor}, - vid, + testconstants.Vid, testconstants.ProductIDsEmpty, aliceName, aliceAccount, @@ -784,7 +782,7 @@ func Demo(suite *utils.TestSuite) { require.Equal(suite.T, jackAccount.Address, certificate.Certs[0].Owner) require.True(suite.T, certificate.Certs[0].IsRoot) - // User (Not Trustee) add Intermediate certificate + // Vandor add Intermediate certificate msgAddX509Cert := pkitypes.MsgAddX509Cert{ Cert: testconstants.IntermediateCertPem, Signer: vendorAccount.Address, @@ -822,12 +820,12 @@ func Demo(suite *utils.TestSuite) { require.Equal(suite.T, vendorAccount.Address, certificate.Certs[0].Owner) require.False(suite.T, certificate.Certs[0].IsRoot) - // Alice (Trustee) add Leaf certificate + // Vandor add Leaf certificate secondMsgAddX509Cert := pkitypes.MsgAddX509Cert{ Cert: testconstants.LeafCertPem, - Signer: aliceAccount.Address, + Signer: vendorAccount.Address, } - _, err = suite.BuildAndBroadcastTx([]sdk.Msg{&secondMsgAddX509Cert}, aliceName, aliceAccount) + _, err = suite.BuildAndBroadcastTx([]sdk.Msg{&secondMsgAddX509Cert}, vendorName, vendorAccount) require.NoError(suite.T, err) // Request all proposed Root certificates @@ -859,7 +857,7 @@ func Demo(suite *utils.TestSuite) { require.Equal(suite.T, testconstants.LeafSubjectKeyID, certificate.SubjectKeyId) require.Equal(suite.T, 1, len(certificate.Certs)) require.Equal(suite.T, testconstants.LeafCertPem, certificate.Certs[0].PemCert) - require.Equal(suite.T, aliceAccount.Address, certificate.Certs[0].Owner) + require.Equal(suite.T, vendorAccount.Address, certificate.Certs[0].Owner) require.Equal(suite.T, testconstants.LeafSubject, certificate.Certs[0].Subject) require.Equal(suite.T, testconstants.LeafSubjectKeyID, certificate.Certs[0].SubjectKeyId) require.Equal(suite.T, testconstants.LeafSubjectAsText, certificate.Certs[0].SubjectAsText) @@ -958,7 +956,7 @@ func Demo(suite *utils.TestSuite) { require.Equal(suite.T, testconstants.LeafSubject, revokedCertificate.Certs[0].Subject) require.Equal(suite.T, testconstants.LeafSubjectKeyID, revokedCertificate.Certs[0].SubjectKeyId) require.Equal(suite.T, testconstants.LeafCertPem, revokedCertificate.Certs[0].PemCert) - require.Equal(suite.T, aliceAccount.Address, revokedCertificate.Certs[0].Owner) + require.Equal(suite.T, vendorAccount.Address, revokedCertificate.Certs[0].Owner) require.Equal(suite.T, testconstants.LeafSubjectAsText, revokedCertificate.Certs[0].SubjectAsText) require.False(suite.T, revokedCertificate.Certs[0].IsRoot) @@ -1701,23 +1699,23 @@ func Demo(suite *utils.TestSuite) { // Add intermediate and leaf certificates msgAddX509Cert = pkitypes.MsgAddX509Cert{ Cert: testconstants.IntermediateWithSameSubjectAndSKID1, - Signer: aliceAccount.Address, + Signer: vendorAccount.Address, } - _, err = suite.BuildAndBroadcastTx([]sdk.Msg{&msgAddX509Cert}, aliceName, aliceAccount) + _, err = suite.BuildAndBroadcastTx([]sdk.Msg{&msgAddX509Cert}, vendorName, vendorAccount) require.NoError(suite.T, err) msgAddX509Cert = pkitypes.MsgAddX509Cert{ Cert: testconstants.IntermediateWithSameSubjectAndSKID2, - Signer: aliceAccount.Address, + Signer: vendorAccount.Address, } - _, err = suite.BuildAndBroadcastTx([]sdk.Msg{&msgAddX509Cert}, aliceName, aliceAccount) + _, err = suite.BuildAndBroadcastTx([]sdk.Msg{&msgAddX509Cert}, vendorName, vendorAccount) require.NoError(suite.T, err) msgAddX509Cert = pkitypes.MsgAddX509Cert{ Cert: testconstants.LeafCertWithSameSubjectAndSKID, - Signer: aliceAccount.Address, + Signer: vendorAccount.Address, } - _, err = suite.BuildAndBroadcastTx([]sdk.Msg{&msgAddX509Cert}, aliceName, aliceAccount) + _, err = suite.BuildAndBroadcastTx([]sdk.Msg{&msgAddX509Cert}, vendorName, vendorAccount) require.NoError(suite.T, err) // Check approved certificate @@ -1733,14 +1731,14 @@ func Demo(suite *utils.TestSuite) { Subject: testconstants.IntermediateCertWithSameSubjectAndSKIDSubject, SubjectKeyId: testconstants.IntermediateCertWithSameSubjectAndSKIDSubjectKeyID, SerialNumber: "invalid", - Signer: aliceAccount.Address, + Signer: vendorAccount.Address, } - _, err = suite.BuildAndBroadcastTx([]sdk.Msg{&msgRevokeX509Cert}, aliceName, aliceAccount) + _, err = suite.BuildAndBroadcastTx([]sdk.Msg{&msgRevokeX509Cert}, vendorName, vendorAccount) require.Error(suite.T, err) // Revoke intermediate certificate with serialNumber 1 only(child certs should not be removed) msgRevokeX509Cert.SerialNumber = testconstants.IntermediateCertWithSameSubjectAndSKID1SerialNumber - _, err = suite.BuildAndBroadcastTx([]sdk.Msg{&msgRevokeX509Cert}, aliceName, aliceAccount) + _, err = suite.BuildAndBroadcastTx([]sdk.Msg{&msgRevokeX509Cert}, vendorName, vendorAccount) require.NoError(suite.T, err) // Request revoked certificate with serialNumber 3 @@ -1813,18 +1811,18 @@ func Demo(suite *utils.TestSuite) { Subject: testconstants.IntermediateCertWithSameSubjectAndSKIDSubject, SubjectKeyId: testconstants.IntermediateCertWithSameSubjectAndSKIDSubjectKeyID, SerialNumber: "invalid", - Signer: aliceAccount.Address, + Signer: vendorAccount.Address, } - _, err = suite.BuildAndBroadcastTx([]sdk.Msg{&msgRemoveX509Cert}, aliceName, aliceAccount) + _, err = suite.BuildAndBroadcastTx([]sdk.Msg{&msgRemoveX509Cert}, vendorName, vendorAccount) require.Error(suite.T, err) // Remove revoked x509 certificate by subject and subject key id msgRemoveX509Cert = pkitypes.MsgRemoveX509Cert{ Subject: testconstants.IntermediateCertWithSameSubjectAndSKIDSubject, SubjectKeyId: testconstants.IntermediateCertWithSameSubjectAndSKIDSubjectKeyID, - Signer: aliceAccount.Address, + Signer: vendorAccount.Address, } - _, err = suite.BuildAndBroadcastTx([]sdk.Msg{&msgRemoveX509Cert}, aliceName, aliceAccount) + _, err = suite.BuildAndBroadcastTx([]sdk.Msg{&msgRemoveX509Cert}, vendorName, vendorAccount) require.NoError(suite.T, err) // Check that two intermediate certificates removed _, err = GetRevokedX509Cert(suite, testconstants.IntermediateCertWithSameSubjectAndSKIDSubject, testconstants.IntermediateCertWithSameSubjectAndSKIDSubjectKeyID) @@ -1836,9 +1834,9 @@ func Demo(suite *utils.TestSuite) { msgRemoveX509Cert = pkitypes.MsgRemoveX509Cert{ Subject: testconstants.LeafCertWithSameSubjectAndSKIDSubject, SubjectKeyId: testconstants.LeafCertWithSameSubjectAndSKIDSubjectKeyID, - Signer: aliceAccount.Address, + Signer: vendorAccount.Address, } - _, err = suite.BuildAndBroadcastTx([]sdk.Msg{&msgRemoveX509Cert}, aliceName, aliceAccount) + _, err = suite.BuildAndBroadcastTx([]sdk.Msg{&msgRemoveX509Cert}, vendorName, vendorAccount) require.NoError(suite.T, err) // Check that leaf certificate removed _, err = GetX509Cert(suite, testconstants.LeafCertWithSameSubjectAndSKIDSubject, testconstants.LeafCertWithSameSubjectAndSKIDSubjectKeyID) @@ -1848,23 +1846,23 @@ func Demo(suite *utils.TestSuite) { // Add intermediate certificates msgAddX509Cert = pkitypes.MsgAddX509Cert{ Cert: testconstants.IntermediateWithSameSubjectAndSKID1, - Signer: aliceAccount.Address, + Signer: vendorAccount.Address, } - _, err = suite.BuildAndBroadcastTx([]sdk.Msg{&msgAddX509Cert}, aliceName, aliceAccount) + _, err = suite.BuildAndBroadcastTx([]sdk.Msg{&msgAddX509Cert}, vendorName, vendorAccount) require.NoError(suite.T, err) msgAddX509Cert = pkitypes.MsgAddX509Cert{ Cert: testconstants.IntermediateWithSameSubjectAndSKID2, - Signer: aliceAccount.Address, + Signer: vendorAccount.Address, } - _, err = suite.BuildAndBroadcastTx([]sdk.Msg{&msgAddX509Cert}, aliceName, aliceAccount) + _, err = suite.BuildAndBroadcastTx([]sdk.Msg{&msgAddX509Cert}, vendorName, vendorAccount) require.NoError(suite.T, err) msgAddX509Cert = pkitypes.MsgAddX509Cert{ Cert: testconstants.LeafCertWithSameSubjectAndSKID, - Signer: aliceAccount.Address, + Signer: vendorAccount.Address, } - _, err = suite.BuildAndBroadcastTx([]sdk.Msg{&msgAddX509Cert}, aliceName, aliceAccount) + _, err = suite.BuildAndBroadcastTx([]sdk.Msg{&msgAddX509Cert}, vendorName, vendorAccount) require.NoError(suite.T, err) // Remove x509 certificate by serial number @@ -1872,9 +1870,9 @@ func Demo(suite *utils.TestSuite) { Subject: testconstants.IntermediateCertWithSameSubjectAndSKIDSubject, SubjectKeyId: testconstants.IntermediateCertWithSameSubjectAndSKIDSubjectKeyID, SerialNumber: testconstants.IntermediateCertWithSameSubjectAndSKID1SerialNumber, - Signer: aliceAccount.Address, + Signer: vendorAccount.Address, } - _, err = suite.BuildAndBroadcastTx([]sdk.Msg{&msgRemoveX509Cert}, aliceName, aliceAccount) + _, err = suite.BuildAndBroadcastTx([]sdk.Msg{&msgRemoveX509Cert}, vendorName, vendorAccount) require.NoError(suite.T, err) // Check that leaf and x509 with different serial number is not removed @@ -1890,9 +1888,9 @@ func Demo(suite *utils.TestSuite) { msgRemoveX509Cert = pkitypes.MsgRemoveX509Cert{ Subject: testconstants.IntermediateCertWithSameSubjectAndSKIDSubject, SubjectKeyId: testconstants.IntermediateCertWithSameSubjectAndSKIDSubjectKeyID, - Signer: aliceAccount.Address, + Signer: vendorAccount.Address, } - _, err = suite.BuildAndBroadcastTx([]sdk.Msg{&msgRemoveX509Cert}, aliceName, aliceAccount) + _, err = suite.BuildAndBroadcastTx([]sdk.Msg{&msgRemoveX509Cert}, vendorName, vendorAccount) require.NoError(suite.T, err) _, err = GetX509Cert(suite, testconstants.IntermediateCertWithSameSubjectAndSKIDSubject, testconstants.IntermediateCertWithSameSubjectAndSKIDSubjectKeyID) @@ -1905,9 +1903,9 @@ func Demo(suite *utils.TestSuite) { msgRemoveX509Cert = pkitypes.MsgRemoveX509Cert{ Subject: testconstants.LeafCertWithSameSubjectAndSKIDSubject, SubjectKeyId: testconstants.LeafCertWithSameSubjectAndSKIDSubjectKeyID, - Signer: aliceAccount.Address, + Signer: vendorAccount.Address, } - _, err = suite.BuildAndBroadcastTx([]sdk.Msg{&msgRemoveX509Cert}, aliceName, aliceAccount) + _, err = suite.BuildAndBroadcastTx([]sdk.Msg{&msgRemoveX509Cert}, vendorName, vendorAccount) require.NoError(suite.T, err) _, err = GetX509Cert(suite, testconstants.LeafCertWithSameSubjectAndSKIDSubject, testconstants.LeafCertWithSameSubjectAndSKIDSubjectKeyID) @@ -1917,16 +1915,16 @@ func Demo(suite *utils.TestSuite) { // Add intermediate and leaf certificates msgAddX509Cert = pkitypes.MsgAddX509Cert{ Cert: testconstants.IntermediateWithSameSubjectAndSKID1, - Signer: aliceAccount.Address, + Signer: vendorAccount.Address, } - _, err = suite.BuildAndBroadcastTx([]sdk.Msg{&msgAddX509Cert}, aliceName, aliceAccount) + _, err = suite.BuildAndBroadcastTx([]sdk.Msg{&msgAddX509Cert}, vendorName, vendorAccount) require.NoError(suite.T, err) msgAddX509Cert = pkitypes.MsgAddX509Cert{ Cert: testconstants.LeafCertWithSameSubjectAndSKID, - Signer: aliceAccount.Address, + Signer: vendorAccount.Address, } - _, err = suite.BuildAndBroadcastTx([]sdk.Msg{&msgAddX509Cert}, aliceName, aliceAccount) + _, err = suite.BuildAndBroadcastTx([]sdk.Msg{&msgAddX509Cert}, vendorName, vendorAccount) require.NoError(suite.T, err) // Check that certs are added From 8df961527d7d02628889a32995b0dc34c142e3c4 Mon Sep 17 00:00:00 2001 From: "aziz.karabashov" Date: Wed, 6 Mar 2024 14:59:25 +0500 Subject: [PATCH 07/14] Add extra integration tests --- .../cli/pki-add-vendor-x509-certificates.sh | 6 ++- integration_tests/grpc_rest/pki/helpers.go | 40 ++++++++++++++++++- 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/integration_tests/cli/pki-add-vendor-x509-certificates.sh b/integration_tests/cli/pki-add-vendor-x509-certificates.sh index d7fec4ca9..1903a7cb2 100755 --- a/integration_tests/cli/pki-add-vendor-x509-certificates.sh +++ b/integration_tests/cli/pki-add-vendor-x509-certificates.sh @@ -34,6 +34,10 @@ check_response "$result" "\"code\": 0" result=$(echo "$passphrase" | dcld tx pki approve-add-x509-root-cert --subject="$root_cert_with_vid_65521_subject" --subject-key-id="$root_cert_with_vid_65521_subject_key_id" --from $second_trustee_account --yes) check_response "$result" "\"code\": 0" +echo "Try to add the intermediate certificate using an account that does not have vendor role" +result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$intermediate_cert_with_vid_65521_path" --from $trustee_account --yes) +check_response "$result" "\"code\": 4" + echo "Add an intermediate certificate with vid=$intermediate_cert_with_vid_65521_vid by $vendor_account_65521 with vid=$vendor_vid_65521" result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$intermediate_cert_with_vid_65521_path" --from $vendor_account_65521 --yes) check_response "$result" "\"code\": 0" @@ -146,7 +150,7 @@ check_response "$result" "\"subject\": \"$intermediate_cert_subject\"" check_response "$result" "\"subjectKeyId\": \"$intermediate_cert_subject_key_id\"" check_response "$result" "\"serialNumber\": \"$intermediate_cert_1_serial_number\"" -echo "Try add second intermediate certificate with same subject and SKID by $vendor_account_65523" +echo "Try to add second intermediate certificate with same subject and SKID by $vendor_account_65523" result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$intermediate_cert_2_path" --from $vendor_account_65523 --yes) check_response "$result" "\"code\": 4" diff --git a/integration_tests/grpc_rest/pki/helpers.go b/integration_tests/grpc_rest/pki/helpers.go index bb1e8aed3..dc5c07cea 100644 --- a/integration_tests/grpc_rest/pki/helpers.go +++ b/integration_tests/grpc_rest/pki/helpers.go @@ -782,8 +782,16 @@ func Demo(suite *utils.TestSuite) { require.Equal(suite.T, jackAccount.Address, certificate.Certs[0].Owner) require.True(suite.T, certificate.Certs[0].IsRoot) - // Vandor add Intermediate certificate + // Try to add Intermediate certificate when sender is not Vendor account msgAddX509Cert := pkitypes.MsgAddX509Cert{ + Cert: testconstants.IntermediateCertPem, + Signer: aliceAccount.Address, + } + _, err = suite.BuildAndBroadcastTx([]sdk.Msg{&msgAddX509Cert}, aliceName, aliceAccount) + require.Error(suite.T, err) + + // Vandor add Intermediate certificate + msgAddX509Cert = pkitypes.MsgAddX509Cert{ Cert: testconstants.IntermediateCertPem, Signer: vendorAccount.Address, } @@ -908,8 +916,18 @@ func Demo(suite *utils.TestSuite) { _, err = GetAllChildX509Certs(suite, testconstants.LeafSubject, testconstants.LeafSubjectKeyID) suite.AssertNotFound(err) - // User (Not Trustee) revokes Intermediate certificate. With `RevokeChild` set to true, its child must also be revoked - Leaf certificate. + // Try to Revoke Intermediate certificate when sender is not Vendor account msgRevokeX509Cert := pkitypes.MsgRevokeX509Cert{ + Subject: testconstants.IntermediateSubject, + SubjectKeyId: testconstants.IntermediateSubjectKeyID, + RevokeChild: true, + Signer: aliceAccount.Address, + } + _, err = suite.BuildAndBroadcastTx([]sdk.Msg{&msgRevokeX509Cert}, aliceName, aliceAccount) + require.Error(suite.T, err) + + // Vendor revokes Intermediate certificate. With `RevokeChild` set to true, its child must also be revoked - Leaf certificate. + msgRevokeX509Cert = pkitypes.MsgRevokeX509Cert{ Subject: testconstants.IntermediateSubject, SubjectKeyId: testconstants.IntermediateSubjectKeyID, RevokeChild: true, @@ -1704,6 +1722,14 @@ func Demo(suite *utils.TestSuite) { _, err = suite.BuildAndBroadcastTx([]sdk.Msg{&msgAddX509Cert}, vendorName, vendorAccount) require.NoError(suite.T, err) + // Try to add second intermediate certificate with same subject and SKID by another Vendor + msgAddX509Cert = pkitypes.MsgAddX509Cert{ + Cert: testconstants.IntermediateWithSameSubjectAndSKID2, + Signer: venAcc65522.Address, + } + _, err = suite.BuildAndBroadcastTx([]sdk.Msg{&msgAddX509Cert}, venName65522, venAcc65522) + require.Error(suite.T, err) + msgAddX509Cert = pkitypes.MsgAddX509Cert{ Cert: testconstants.IntermediateWithSameSubjectAndSKID2, Signer: vendorAccount.Address, @@ -1816,6 +1842,16 @@ func Demo(suite *utils.TestSuite) { _, err = suite.BuildAndBroadcastTx([]sdk.Msg{&msgRemoveX509Cert}, vendorName, vendorAccount) require.Error(suite.T, err) + // Try to Remove x509 certificate by subject and subject key id when sender is not Vendor account + msgRemoveX509Cert = pkitypes.MsgRemoveX509Cert{ + Subject: testconstants.IntermediateCertWithSameSubjectAndSKIDSubject, + SubjectKeyId: testconstants.IntermediateCertWithSameSubjectAndSKIDSubjectKeyID, + SerialNumber: "invalid", + Signer: aliceAccount.Address, + } + _, err = suite.BuildAndBroadcastTx([]sdk.Msg{&msgRemoveX509Cert}, aliceName, aliceAccount) + require.Error(suite.T, err) + // Remove revoked x509 certificate by subject and subject key id msgRemoveX509Cert = pkitypes.MsgRemoveX509Cert{ Subject: testconstants.IntermediateCertWithSameSubjectAndSKIDSubject, From 15c51d40ef2eac299b446cde4a6ce0c1e7a65b91 Mon Sep 17 00:00:00 2001 From: "aziz.karabashov" Date: Wed, 6 Mar 2024 16:28:36 +0500 Subject: [PATCH 08/14] Update documentation for add/revoke/remove transactions --- docs/transactions.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/docs/transactions.md b/docs/transactions.md index 24c515401..3cb39b2f0 100644 --- a/docs/transactions.md +++ b/docs/transactions.md @@ -905,13 +905,17 @@ already present on the ledger. The certificate is immutable. It can only be revoked by either the owner or a quorum of Trustees. +- Who can send: Vendor account + - PAA (Root certificates) are VID-scoped: + - the `vid` field in the subject of the intermediate/leaf X509 certificate must be equal to the Vendor account's VID. + - Non-VID scoped PAAs (Root certificates): + - if the intermediate/leaf X509 certificate is VID-scoped, then the `vid` field in the certificate must match the corresponding PAA's `vid` field on the ledger, or the intermediate/leaf X509 certificate must not be VID-scoped. + - `vid` field associated with the corresponding PAA on the ledger must be equal to the Vendor account's VID. - Parameters: - cert: `string` - PEM encoded certificate. The corresponding CLI parameter can contain either a PEM string or a path to a file containing the data. - In State: - `pki/ApprovedCertificates/value//` - `pki/ChildCertificates/value//` -- Who can send: - - Any role - CLI command: - `dcld tx pki add-x509-cert --certificate= --from=` - Validation: @@ -921,7 +925,7 @@ The certificate is immutable. It can only be revoked by either the owner or a qu - no existing certificate with the same `:` combination. - if certificates with the same `:` combination already exist: - the existing certificate must not be NOC certificate - - sender must match to the owner of the existing certificates. + - the sender's VID must match the vid field of the existing certificates. - the signature (self-signature) and expiration date are valid. - parent certificate must be already stored on the ledger and a valid chain to some root certificate can be built. @@ -941,6 +945,8 @@ If `revoke-child` flag is set to `true` then all the certificates in the chain s Only the owner (sender) can revoke the certificate. Root certificates can not be revoked this way, use `PROPOSE_X509_CERT_REVOC` and `APPROVE_X509_ROOT_CERT_REVOC` instead. +- Who can send: Vendor account + - the sender's VID must match the vid field of the revoking certificates. - Parameters: - subject: `string` - certificates's `Subject` is base64 encoded subject DER sequence bytes - subject_key_id: `string` - certificates's `Subject Key Id` in hex string format, e.g: `5A:88:0E:6C:36:53:D0:7F:B0:89:71:A3:F4:73:79:09:30:E6:2B:DB` @@ -949,8 +955,6 @@ Root certificates can not be revoked this way, use `PROPOSE_X509_CERT_REVOC` an - info: `optional(string)` - information/notes for the revocation - time: `optional(int64)` - revocation time (number of nanoseconds elapsed since January 1, 1970 UTC). CLI uses the current time for that field. - In State: `pki/RevokedCertificates/value//` -- Who can send: - - Any role; owner - CLI command: - `dcld tx pki revoke-x509-cert --subject= --subject-key-id= --from=` @@ -963,6 +967,8 @@ Removes the given X509 certificate (either intermediate or leaf) from approved a Only the owner (sender) can remove the certificate. Root certificates can not be removed this way. +- Who can send: Vendor account + - the sender's VID must match the vid field of the removing certificates. - Parameters: - subject: `string` - certificates's `Subject` is base64 encoded subject DER sequence bytes - subject_key_id: `string` - certificates's `Subject Key Id` in hex string format, e.g: `5A:88:0E:6C:36:53:D0:7F:B0:89:71:A3:F4:73:79:09:30:E6:2B:DB` @@ -1041,7 +1047,6 @@ Publishing the revocation distribution endpoint doesn't automatically remove PAI and DACs (leaf certificates) added to DCL if they are revoked in the CRL identified by this distribution point. [REVOKE_X509_CERT](#revoke_x509_cert) needs to be called to remove an intermediate or leaf certificate from the ledger. - - Who can send: Vendor account - `vid` field in the transaction (`VendorID`) must be equal to the Vendor account's VID - VID-scoped PAAs (Root certs) and PAIs (Intermediate certs): `vid` field in the `CRLSignerCertificate`'s subject must be equal to the Vendor account's VID From ad8a11bac26bd3e3f112bcb243e7951d29221b9c Mon Sep 17 00:00:00 2001 From: "aziz.karabashov" Date: Wed, 6 Mar 2024 17:04:50 +0500 Subject: [PATCH 09/14] Fix transaction doc --- docs/transactions.md | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/docs/transactions.md b/docs/transactions.md index 3cb39b2f0..7cf4ffe8b 100644 --- a/docs/transactions.md +++ b/docs/transactions.md @@ -925,7 +925,7 @@ The certificate is immutable. It can only be revoked by either the owner or a qu - no existing certificate with the same `:` combination. - if certificates with the same `:` combination already exist: - the existing certificate must not be NOC certificate - - the sender's VID must match the vid field of the existing certificates. + - the sender's VID must match the `vid` field of the existing certificates. - the signature (self-signature) and expiration date are valid. - parent certificate must be already stored on the ledger and a valid chain to some root certificate can be built. @@ -942,11 +942,10 @@ If a Revocation Distribution Point needs to be published (such as RFC5280 Certif If `revoke-child` flag is set to `true` then all the certificates in the chain signed by the revoked certificate will be revoked as well. -Only the owner (sender) can revoke the certificate. Root certificates can not be revoked this way, use `PROPOSE_X509_CERT_REVOC` and `APPROVE_X509_ROOT_CERT_REVOC` instead. - Who can send: Vendor account - - the sender's VID must match the vid field of the revoking certificates. + - the sender's VID must match the `vid` field of the revoking certificates. - Parameters: - subject: `string` - certificates's `Subject` is base64 encoded subject DER sequence bytes - subject_key_id: `string` - certificates's `Subject Key Id` in hex string format, e.g: `5A:88:0E:6C:36:53:D0:7F:B0:89:71:A3:F4:73:79:09:30:E6:2B:DB` @@ -964,17 +963,14 @@ Root certificates can not be revoked this way, use `PROPOSE_X509_CERT_REVOC` an Removes the given X509 certificate (either intermediate or leaf) from approved and revoked certificates list. -Only the owner (sender) can remove the certificate. Root certificates can not be removed this way. - Who can send: Vendor account - - the sender's VID must match the vid field of the removing certificates. + - the sender's VID must match the `vid` field of the removing certificates. - Parameters: - subject: `string` - certificates's `Subject` is base64 encoded subject DER sequence bytes - subject_key_id: `string` - certificates's `Subject Key Id` in hex string format, e.g: `5A:88:0E:6C:36:53:D0:7F:B0:89:71:A3:F4:73:79:09:30:E6:2B:DB` - serial-number: `optional(string)` - certificate's serial number -- Who can send: - - Any role; owner - CLI command: - `dcld tx pki remove-x509-cert --subject= --subject-key-id= --from=` @@ -1145,7 +1141,7 @@ This transaction adds a NOC root certificate owned by the Vendor. - no existing certificate with the same `:` combination. - if certificates with the same `:` combination already exist: - the existing certificate must be NOC root certificate - - the sender's VID must match the vid field of the existing certificates. + - the sender's VID must match the `vid` field of the existing certificates. - the signature (self-signature) and expiration date must be valid. - Parameters: - cert: `string` - The NOC Root Certificate, encoded in X.509v3 PEM format. Can be a PEM string or a file path. From f05443e477b1057ed82dd8067f59acc7a79e34e8 Mon Sep 17 00:00:00 2001 From: "aziz.karabashov" Date: Wed, 6 Mar 2024 17:33:58 +0500 Subject: [PATCH 10/14] Fix merge issues --- x/pki/handler_add_noc_cert_test.go | 15 +++++---------- x/pki/keeper/msg_server_add_noc_x_509_cert.go | 4 ++-- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/x/pki/handler_add_noc_cert_test.go b/x/pki/handler_add_noc_cert_test.go index d83d667d0..9fcd1a763 100644 --- a/x/pki/handler_add_noc_cert_test.go +++ b/x/pki/handler_add_noc_cert_test.go @@ -19,8 +19,7 @@ func TestHandler_AddNocX509Cert_SenderNotVendor(t *testing.T) { addNocX509Cert := types.NewMsgAddNocX509Cert(setup.Trustee1.String(), testconstants.NocCert1) _, err := setup.Handler(setup.Ctx, addNocX509Cert) - require.Error(t, err) - require.True(t, sdkerrors.ErrUnauthorized.Is(err)) + require.ErrorIs(t, err, sdkerrors.ErrUnauthorized) } func TestHandler_AddNocX509Cert_AddNew(t *testing.T) { @@ -160,8 +159,7 @@ func TestHandler_AddNocX509Cert_Root_VID_Does_Not_Equal_To_AccountVID(t *testing // try to add NOC certificate nocX509Cert := types.NewMsgAddNocX509Cert(newAccAddress.String(), testconstants.NocCert1) _, err := setup.Handler(setup.Ctx, nocX509Cert) - require.Error(t, err) - require.True(t, pkitypes.ErrCertVidNotEqualAccountVid.Is(err)) + require.ErrorIs(t, err, pkitypes.ErrCertVidNotEqualAccountVid) } func TestHandler_AddNocX509Cert_ForInvalidCertificate(t *testing.T) { @@ -174,8 +172,7 @@ func TestHandler_AddNocX509Cert_ForInvalidCertificate(t *testing.T) { // add x509 certificate addX509Cert := types.NewMsgAddNocX509Cert(accAddress.String(), testconstants.StubCertPem) _, err := setup.Handler(setup.Ctx, addX509Cert) - require.Error(t, err) - require.True(t, pkitypes.ErrInvalidCertificate.Is(err)) + require.ErrorIs(t, err, pkitypes.ErrInvalidCertificate) } func TestHandler_AddXNoc509Cert_ForNocRootCertificate(t *testing.T) { @@ -188,8 +185,7 @@ func TestHandler_AddXNoc509Cert_ForNocRootCertificate(t *testing.T) { // try to add root certificate x509 certificate addX509Cert := types.NewMsgAddX509Cert(accAddress.String(), testconstants.NocRootCert1) _, err := setup.Handler(setup.Ctx, addX509Cert) - require.Error(t, err) - require.True(t, pkitypes.ErrInappropriateCertificateType.Is(err)) + require.ErrorIs(t, err, pkitypes.ErrNonRootCertificateSelfSigned) } func TestHandler_AddXNoc509Cert_ForRootNonNocCertificate(t *testing.T) { @@ -212,7 +208,6 @@ func TestHandler_AddXNoc509Cert_ForRootNonNocCertificate(t *testing.T) { // try to add root certificate x509 certificate addX509Cert := types.NewMsgAddNocX509Cert(accAddress.String(), testconstants.IntermediateCertWithVid1) _, err := setup.Handler(setup.Ctx, addX509Cert) - require.Error(t, err) require.ErrorIs(t, err, pkitypes.ErrInappropriateCertificateType) } @@ -333,7 +328,7 @@ func TestHandler_AddNocX509Cert_CertificateExist(t *testing.T) { Vid: testconstants.VendorID1, }, nocCert: testconstants.NocCert1, - err: pkitypes.ErrCertVidNotEqualAccountVid, + err: sdkerrors.ErrUnauthorized, }, } diff --git a/x/pki/keeper/msg_server_add_noc_x_509_cert.go b/x/pki/keeper/msg_server_add_noc_x_509_cert.go index f65162376..8d44f2161 100644 --- a/x/pki/keeper/msg_server_add_noc_x_509_cert.go +++ b/x/pki/keeper/msg_server_add_noc_x_509_cert.go @@ -62,7 +62,7 @@ func (k msgServer) AddNocX509Cert(goCtx context.Context, msg *types.MsgAddNocX50 // signer VID must be same as VID of existing certificates if accountVid != existingCertificate.Vid { - return nil, pkitypes.NewErrExistingCertVidNotEqualAccountVid( + return nil, pkitypes.NewErrUnauthorizedCertVendor( x509Certificate.Subject, x509Certificate.SubjectKeyID, existingCertificate.Vid, @@ -86,7 +86,7 @@ func (k msgServer) AddNocX509Cert(goCtx context.Context, msg *types.MsgAddNocX50 } // Check VID scoping if nocRootCert.Vid != accountVid { - return nil, pkitypes.NewErrAccountVidNotEqualToCertVid(accountVid, nocRootCert.Vid) + return nil, pkitypes.NewErrRootCertVidNotEqualToAccountVid(accountVid, nocRootCert.Vid) } // create new certificate From 7b86d9fcb4d1c61dff5c277cf5cf89b66b4f63ce Mon Sep 17 00:00:00 2001 From: "aziz.karabashov" Date: Wed, 6 Mar 2024 19:15:42 +0500 Subject: [PATCH 11/14] Fix linter issues and integration tests --- integration_tests/light_client_proxy/pki.sh | 21 ++++++++++--------- .../upgrade/test-upgrade-0.12-to-1.2.sh | 4 ++-- .../upgrade/test-upgrade-1.2-to-1.3.sh | 6 +++--- x/pki/handler_add_non_root_cert_test.go | 10 ++++----- x/pki/keeper/msg_server_add_x_509_cert.go | 2 +- 5 files changed, 22 insertions(+), 21 deletions(-) mode change 100644 => 100755 integration_tests/light_client_proxy/pki.sh diff --git a/integration_tests/light_client_proxy/pki.sh b/integration_tests/light_client_proxy/pki.sh old mode 100644 new mode 100755 index a83a8ba08..68a3e5e5b --- a/integration_tests/light_client_proxy/pki.sh +++ b/integration_tests/light_client_proxy/pki.sh @@ -131,14 +131,15 @@ dcld config node tcp://localhost:26657 trustee_account="jack" second_trustee_account="alice" -echo "Create regular account" -create_new_account user_account "CertificationCenter" +vendor_account=vendor_account_$vid +echo "Create Vendor account - $vendor_account" +create_new_vendor_account $vendor_account $vid test_divider -echo "$user_account (Not Trustee) propose Root certificate" +echo "$vendor_account (Not Trustee) propose Root certificate" root_path="integration_tests/constants/root_cert" -result=$(echo "$passphrase" | dcld tx pki propose-add-x509-root-cert --certificate="$root_path" --vid $vid --from $user_account --yes) +result=$(echo "$passphrase" | dcld tx pki propose-add-x509-root-cert --certificate="$root_path" --vid $vid --from $vendor_account --yes) response_does_not_contain "$result" "\"code\": 0" echo "$result" @@ -159,24 +160,24 @@ echo "$result" test_divider -echo "$user_account (Not Trustee) add Intermediate certificate" +echo "$vendor_account (Vendor) add Intermediate certificate" intermediate_path="integration_tests/constants/intermediate_cert" -result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$intermediate_path" --from $user_account --yes) +result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$intermediate_path" --from $vendor_account --yes) check_response "$result" "\"code\": 0" echo "$result" test_divider -echo "$trustee_account (Trustee) add Leaf certificate" +echo "$vendor_account (Vendor) add Leaf certificate" leaf_path="integration_tests/constants/leaf_cert" -result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$leaf_path" --from $trustee_account --yes) +result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$leaf_path" --from $vendor_account --yes) check_response "$result" "\"code\": 0" echo "$result" test_divider -echo "$trustee_account (Trustee) revokes Leaf certificate." -result=$(echo "$passphrase" | dcld tx pki revoke-x509-cert --subject="$leaf_cert_subject" --subject-key-id="$leaf_cert_subject_key_id" --from=$trustee_account --yes) +echo "$vendor_account (Vendor) revokes Leaf certificate." +result=$(echo "$passphrase" | dcld tx pki revoke-x509-cert --subject="$leaf_cert_subject" --subject-key-id="$leaf_cert_subject_key_id" --from=$vendor_account --yes) check_response "$result" "\"code\": 0" echo "$result" diff --git a/integration_tests/upgrade/test-upgrade-0.12-to-1.2.sh b/integration_tests/upgrade/test-upgrade-0.12-to-1.2.sh index ef9cd2dd7..a111aca12 100755 --- a/integration_tests/upgrade/test-upgrade-0.12-to-1.2.sh +++ b/integration_tests/upgrade/test-upgrade-0.12-to-1.2.sh @@ -1139,13 +1139,13 @@ check_response "$result" "\"code\": 0" test_divider echo "Add intermediate_cert" -result=$(echo $passphrase | $DCLD_BIN_NEW tx pki add-x509-cert --certificate="$intermediate_cert_path_new" --from=$trustee_account_1 --yes) +result=$(echo $passphrase | $DCLD_BIN_NEW tx pki add-x509-cert --certificate="$intermediate_cert_path_new" --from=$vendor_account --yes) check_response "$result" "\"code\": 0" test_divider echo "Revoke intermediate_cert" -result=$(echo $passphrase | $DCLD_BIN_NEW tx pki revoke-x509-cert --subject="$intermediate_cert_subject_new" --subject-key-id="$intermediate_cert_subject_key_id_new" --from=$trustee_account_1 --yes) +result=$(echo $passphrase | $DCLD_BIN_NEW tx pki revoke-x509-cert --subject="$intermediate_cert_subject_new" --subject-key-id="$intermediate_cert_subject_key_id_new" --from=$vendor_account --yes) check_response "$result" "\"code\": 0" test_divider diff --git a/integration_tests/upgrade/test-upgrade-1.2-to-1.3.sh b/integration_tests/upgrade/test-upgrade-1.2-to-1.3.sh index 326c33fd3..680dd4c6d 100755 --- a/integration_tests/upgrade/test-upgrade-1.2-to-1.3.sh +++ b/integration_tests/upgrade/test-upgrade-1.2-to-1.3.sh @@ -473,7 +473,7 @@ check_response "$result" "\"code\": 0" test_divider echo "Add intermediate_cert" -result=$(echo $passphrase | $DCLD_BIN_OLD tx pki add-x509-cert --certificate="$intermediate_cert_path" --from=$trustee_account_1 --yes) +result=$(echo $passphrase | $DCLD_BIN_OLD tx pki add-x509-cert --certificate="$intermediate_cert_path" --from=$vendor_account --yes) check_response "$result" "\"code\": 0" test_divider @@ -1176,7 +1176,7 @@ check_response "$result" "\"code\": 0" test_divider echo "Add intermediate_cert" -result=$(echo $passphrase | $DCLD_BIN_NEW tx pki add-x509-cert --certificate="$intermediate_cert_path_new" --from=$trustee_account_1 --yes) +result=$(echo $passphrase | $DCLD_BIN_NEW tx pki add-x509-cert --certificate="$intermediate_cert_path_new" --from=$vendor_account --yes) check_response "$result" "\"code\": 0" test_divider @@ -1188,7 +1188,7 @@ check_response "$result" "\"subjectKeyId\": \"$intermediate_cert_subject_key_id_ test_divider echo "Revoke intermediate_cert" -result=$(echo $passphrase | $DCLD_BIN_NEW tx pki revoke-x509-cert --subject="$intermediate_cert_subject_new" --subject-key-id="$intermediate_cert_subject_key_id_new" --from=$trustee_account_1 --yes) +result=$(echo $passphrase | $DCLD_BIN_NEW tx pki revoke-x509-cert --subject="$intermediate_cert_subject_new" --subject-key-id="$intermediate_cert_subject_key_id_new" --from=$vendor_account --yes) check_response "$result" "\"code\": 0" test_divider diff --git a/x/pki/handler_add_non_root_cert_test.go b/x/pki/handler_add_non_root_cert_test.go index 879aba78e..93b3982ef 100644 --- a/x/pki/handler_add_non_root_cert_test.go +++ b/x/pki/handler_add_non_root_cert_test.go @@ -503,7 +503,7 @@ func TestHandler_AddX509Cert_NonVIDScopedRoot(t *testing.T) { rootCertOptions *rootCertOptions childCert string childCertSubject string - childCertSubjectKeyId string + childCertSubjectKeyID string accountVid int32 }{ { @@ -511,7 +511,7 @@ func TestHandler_AddX509Cert_NonVIDScopedRoot(t *testing.T) { rootCertOptions: createPAACertNoVidOptions(testconstants.PAICertWithVidVid), childCert: testconstants.PAICertWithNumericVid, childCertSubject: testconstants.PAICertWithNumericVidSubject, - childCertSubjectKeyId: testconstants.PAICertWithNumericVidSubjectKeyID, + childCertSubjectKeyID: testconstants.PAICertWithNumericVidSubjectKeyID, accountVid: testconstants.PAICertWithVidVid, }, { @@ -519,7 +519,7 @@ func TestHandler_AddX509Cert_NonVIDScopedRoot(t *testing.T) { rootCertOptions: createTestRootCertOptions(), childCert: testconstants.IntermediateCertPem, childCertSubject: testconstants.IntermediateSubject, - childCertSubjectKeyId: testconstants.IntermediateSubjectKeyID, + childCertSubjectKeyID: testconstants.IntermediateSubjectKeyID, accountVid: testconstants.Vid, }, } @@ -541,10 +541,10 @@ func TestHandler_AddX509Cert_NonVIDScopedRoot(t *testing.T) { // query certificate certs, _ := queryAllApprovedCertificates(setup) require.Equal(t, 2, len(certs)) - intermediateCerts, _ := queryApprovedCertificates(setup, tc.childCertSubject, tc.childCertSubjectKeyId) + intermediateCerts, _ := queryApprovedCertificates(setup, tc.childCertSubject, tc.childCertSubjectKeyID) require.Equal(t, 1, len(intermediateCerts.Certs)) require.Equal(t, tc.childCertSubject, intermediateCerts.Certs[0].Subject) - require.Equal(t, tc.childCertSubjectKeyId, intermediateCerts.Certs[0].SubjectKeyId) + require.Equal(t, tc.childCertSubjectKeyID, intermediateCerts.Certs[0].SubjectKeyId) }) } } diff --git a/x/pki/keeper/msg_server_add_x_509_cert.go b/x/pki/keeper/msg_server_add_x_509_cert.go index b0b9e6fb1..d0638bdee 100644 --- a/x/pki/keeper/msg_server_add_x_509_cert.go +++ b/x/pki/keeper/msg_server_add_x_509_cert.go @@ -146,7 +146,7 @@ func (k msgServer) ensureCertsAndSenderVidMatch( signerAccount, _ := k.dclauthKeeper.GetAccountO(ctx, signerAddr) accountVID := signerAccount.VendorID - if rootVid != 0 { + if rootVid != 0 { //nolint:nestif // If added under a VID scoped root CA: // Child certificate must be also VID scoped to the same VID as a root one if rootVid != childVid { From 4e307bfb7a024b5df30232ff93bb241c22f768d4 Mon Sep 17 00:00:00 2001 From: "aziz.karabashov" Date: Wed, 6 Mar 2024 19:46:05 +0500 Subject: [PATCH 12/14] Fix ligh client proxy test --- integration_tests/light_client_proxy/pki.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration_tests/light_client_proxy/pki.sh b/integration_tests/light_client_proxy/pki.sh index 68a3e5e5b..cb6f10156 100755 --- a/integration_tests/light_client_proxy/pki.sh +++ b/integration_tests/light_client_proxy/pki.sh @@ -313,7 +313,7 @@ echo "try to write via light client proxy" test_divider echo "Add cert" -result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$intermediate_path" --from $user_account --yes) +result=$(echo "$passphrase" | dcld tx pki add-x509-cert --certificate="$intermediate_path" --from $vendor_account --yes) echo "$result" check_response "$result" "Write requests don't work with a Light Client Proxy" From e91830f897aecc4f21d1191496ddd11783ebe4b4 Mon Sep 17 00:00:00 2001 From: "aziz.karabashov" Date: Thu, 7 Mar 2024 11:26:20 +0500 Subject: [PATCH 13/14] Clarify the validations for the ADD_X509_CERT transaction --- docs/transactions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/transactions.md b/docs/transactions.md index e98e29675..5b5f1ca36 100644 --- a/docs/transactions.md +++ b/docs/transactions.md @@ -907,7 +907,7 @@ The certificate is immutable. It can only be revoked by either the owner or a qu - Who can send: Vendor account - PAA (Root certificates) are VID-scoped: - - the `vid` field in the subject of the intermediate/leaf X509 certificate must be equal to the Vendor account's VID. + - the vid field in the subject of the root certificate, as well as in the intermediate/leaf X509 certificates and the Vendor account's VID certificate, must be the same. - Non-VID scoped PAAs (Root certificates): - if the intermediate/leaf X509 certificate is VID-scoped, then the `vid` field in the certificate must match the corresponding PAA's `vid` field on the ledger, or the intermediate/leaf X509 certificate must not be VID-scoped. - `vid` field associated with the corresponding PAA on the ledger must be equal to the Vendor account's VID. From 01f4501eda21d49c5f95f721b89b0c52c7e9b77a Mon Sep 17 00:00:00 2001 From: "aziz.karabashov" Date: Thu, 7 Mar 2024 15:25:41 +0500 Subject: [PATCH 14/14] Fix typo and naming --- integration_tests/cli/pki-demo.sh | 2 +- integration_tests/cli/pki-remove-x509-certificates.sh | 2 +- types/pki/errors.go | 8 ++++---- x/pki/handler_add_non_root_cert_test.go | 2 +- x/pki/handler_test.go | 4 ++-- x/pki/keeper/keeper.go | 6 +++--- x/pki/keeper/msg_server_add_noc_x_509_cert.go | 6 +----- x/pki/keeper/msg_server_add_noc_x_509_root_cert.go | 6 +----- x/pki/keeper/msg_server_add_x_509_cert.go | 10 +++++----- x/pki/keeper/msg_server_remove_x_509_cert.go | 4 ++-- x/pki/keeper/msg_server_revoke_x_509_cert.go | 4 ++-- 11 files changed, 23 insertions(+), 31 deletions(-) diff --git a/integration_tests/cli/pki-demo.sh b/integration_tests/cli/pki-demo.sh index 893af44a4..ec0d2b231 100755 --- a/integration_tests/cli/pki-demo.sh +++ b/integration_tests/cli/pki-demo.sh @@ -658,7 +658,7 @@ test_divider echo "6. REVOKE INTERMEDIATE (AND HENCE LEAF) CERTS - No Approvals needed" test_divider -echo "Try to revoke the intermediate certificate using an account that does not have vendor role" +echo "Try to revoke the intermediate certificate when sender is not Vendor account" result=$(echo "$passphrase" | dcld tx pki revoke-x509-cert --subject="$intermediate_cert_subject" --subject-key-id="$intermediate_cert_subject_key_id" --from=$user_account --yes) check_response "$result" "\"code\": 4" diff --git a/integration_tests/cli/pki-remove-x509-certificates.sh b/integration_tests/cli/pki-remove-x509-certificates.sh index 209c7f033..f7024e38d 100755 --- a/integration_tests/cli/pki-remove-x509-certificates.sh +++ b/integration_tests/cli/pki-remove-x509-certificates.sh @@ -79,7 +79,7 @@ echo "Remove intermediate certificate with invalid serialNumber" result=$(echo "$passphrase" | dcld tx pki remove-x509-cert --subject="$intermediate_cert_subject" --subject-key-id="$intermediate_cert_subject_key_id" --serial-number="invalid" --from=$vendor_account_65521 --yes) check_response "$result" "\"code\": 404" -echo "Try to remove the intermediate certificate using an account that does not have vendor role" +echo "Try to remove the intermediate certificate when sender is not Vendor account" result=$(echo "$passphrase" | dcld tx pki remove-x509-cert --subject="$intermediate_cert_subject" --subject-key-id="$intermediate_cert_subject_key_id" --serial-number="$intermediate_cert_1_serial_number" --from=$trustee_account --yes) check_response "$result" "\"code\": 4" diff --git a/types/pki/errors.go b/types/pki/errors.go index 4754cc2c8..bfaca2bee 100644 --- a/types/pki/errors.go +++ b/types/pki/errors.go @@ -188,11 +188,11 @@ func NewErrUnauthorizedCertOwner(subject string, subjectKeyID string) error { subject, subjectKeyID) } -func NewErrUnauthorizedCertVendor(subject string, subjectKeyID string, ownerVid int32) error { +func NewErrUnauthorizedCertVendor(ownerVid int32) error { return sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "Only the vendor accounts with vid=%d, has the authority "+ - "to add, remove, or revoke a certificate with subject=%v and subjectKeyID=%v", - ownerVid, subject, subjectKeyID) + "to add, remove, or revoke a certificate with provided subject and subjectKeyID", + ownerVid) } func NewErrProvidedNocCertButExistingNotNoc(subject string, subjectKeyID string) error { @@ -226,7 +226,7 @@ func NewErrRootCertVidNotEqualToCertVid(rootVID int32, certVID int32) error { func NewErrRootCertVidNotEqualToAccountVid(rootVID int32, accountVID int32) error { return sdkerrors.Wrapf(ErrCertVidNotEqualAccountVid, - "Only a Vendor associated with root certificate VID can add a child certificate: "+ + "Only a Vendor associated with VID of root certificate can add a child certificate: "+ "Root certificate's VID = %v, Account VID = %v", rootVID, accountVID) } diff --git a/x/pki/handler_add_non_root_cert_test.go b/x/pki/handler_add_non_root_cert_test.go index 93b3982ef..34aeda65a 100644 --- a/x/pki/handler_add_non_root_cert_test.go +++ b/x/pki/handler_add_non_root_cert_test.go @@ -134,7 +134,7 @@ func TestHandler_AddX509Cert_ForExistingNocCertificate(t *testing.T) { nocCertificate.IsNoc = true setup.Keeper.AddApprovedCertificate(setup.Ctx, nocCertificate) - // TODO: add the certificate to the ICA store after the store is implemented + setup.Keeper.AddNocCertificate(setup.Ctx, nocCertificate) uniqueCertificate := types.UniqueCertificate{ Issuer: nocCertificate.Issuer, SerialNumber: nocCertificate.SerialNumber, diff --git a/x/pki/handler_test.go b/x/pki/handler_test.go index aa4023800..7faeb0606 100644 --- a/x/pki/handler_test.go +++ b/x/pki/handler_test.go @@ -752,7 +752,7 @@ func TestHandler_ProposeRevokeX509RootCert_ByTrusteeNotOwner(t *testing.T) { rootCertOptions := createTestRootCertOptions() proposeAndApproveRootCertificate(setup, setup.Trustee1, rootCertOptions) - // store another trustee + // add another trustee anotherTrustee := GenerateAccAddress() setup.AddAccount(anotherTrustee, []dclauthtypes.AccountRole{dclauthtypes.Trustee}, 1) @@ -1211,7 +1211,7 @@ func TestHandler_ApproveRevokeX509RootCert_ForTree(t *testing.T) { require.Equal(t, 1, len(allRevokedCertificates[2].Certs)) require.Equal(t, testconstants.IntermediateCertPem, allRevokedCertificates[2].Certs[0].PemCert) - // check that no certificates stays approved + // check that approved certs list is empty allApprovedCertificates, err := queryAllApprovedCertificates(setup) require.NoError(t, err) require.Equal(t, 0, len(allApprovedCertificates)) diff --git a/x/pki/keeper/keeper.go b/x/pki/keeper/keeper.go index d14df518c..85c1ae684 100644 --- a/x/pki/keeper/keeper.go +++ b/x/pki/keeper/keeper.go @@ -51,7 +51,7 @@ func (k Keeper) CertificateRejectApprovalsCount(ctx sdk.Context, authKeeper type return authKeeper.CountAccountsWithRole(ctx, authTypes.Trustee) - k.CertificateApprovalsCount(ctx, authKeeper) + 1 } -func (k Keeper) EnsureSenderAndOwnerVidMatch(ctx sdk.Context, certificate *types.Certificate, signer string) error { +func (k Keeper) EnsureVidMatches(ctx sdk.Context, owner string, signer string) error { // get signer VID signerAddr, err := sdk.AccAddressFromBech32(signer) if err != nil { @@ -62,7 +62,7 @@ func (k Keeper) EnsureSenderAndOwnerVidMatch(ctx sdk.Context, certificate *types signerVid := signerAccount.VendorID // get owner VID - ownerAddr, err := sdk.AccAddressFromBech32(certificate.Owner) + ownerAddr, err := sdk.AccAddressFromBech32(owner) if err != nil { return pkitypes.NewErrInvalidAddress(err) } @@ -71,7 +71,7 @@ func (k Keeper) EnsureSenderAndOwnerVidMatch(ctx sdk.Context, certificate *types ownerVid := ownerAccount.VendorID if signerVid != ownerVid { - return pkitypes.NewErrUnauthorizedCertVendor(certificate.Subject, certificate.SubjectKeyId, ownerVid) + return pkitypes.NewErrUnauthorizedCertVendor(ownerVid) } return nil diff --git a/x/pki/keeper/msg_server_add_noc_x_509_cert.go b/x/pki/keeper/msg_server_add_noc_x_509_cert.go index 8d44f2161..7eb9ae6d5 100644 --- a/x/pki/keeper/msg_server_add_noc_x_509_cert.go +++ b/x/pki/keeper/msg_server_add_noc_x_509_cert.go @@ -62,11 +62,7 @@ func (k msgServer) AddNocX509Cert(goCtx context.Context, msg *types.MsgAddNocX50 // signer VID must be same as VID of existing certificates if accountVid != existingCertificate.Vid { - return nil, pkitypes.NewErrUnauthorizedCertVendor( - x509Certificate.Subject, - x509Certificate.SubjectKeyID, - existingCertificate.Vid, - ) + return nil, pkitypes.NewErrUnauthorizedCertVendor(existingCertificate.Vid) } } // Valid certificate chain must be built for new certificate diff --git a/x/pki/keeper/msg_server_add_noc_x_509_root_cert.go b/x/pki/keeper/msg_server_add_noc_x_509_root_cert.go index d1aa95f3c..813b22e83 100644 --- a/x/pki/keeper/msg_server_add_noc_x_509_root_cert.go +++ b/x/pki/keeper/msg_server_add_noc_x_509_root_cert.go @@ -68,11 +68,7 @@ func (k msgServer) AddNocX509RootCert(goCtx context.Context, msg *types.MsgAddNo // signer VID must be same as VID of existing certificates if signerVid != existingCertificate.Vid { - return nil, pkitypes.NewErrUnauthorizedCertVendor( - x509Certificate.Subject, - x509Certificate.SubjectKeyID, - existingCertificate.Vid, - ) + return nil, pkitypes.NewErrUnauthorizedCertVendor(existingCertificate.Vid) } } diff --git a/x/pki/keeper/msg_server_add_x_509_cert.go b/x/pki/keeper/msg_server_add_x_509_cert.go index d0638bdee..08204c66e 100644 --- a/x/pki/keeper/msg_server_add_x_509_cert.go +++ b/x/pki/keeper/msg_server_add_x_509_cert.go @@ -21,7 +21,7 @@ func (k msgServer) AddX509Cert(goCtx context.Context, msg *types.MsgAddX509Cert) // check if signer has vendor role if !k.dclauthKeeper.HasRole(ctx, signerAddr, dclauthtypes.Vendor) { - return nil, pkitypes.NewErrUnauthorizedRole("MsgAddNocX509RootCert", dclauthtypes.Vendor) + return nil, pkitypes.NewErrUnauthorizedRole("MsgAddX509Cert", dclauthtypes.Vendor) } // decode pem certificate @@ -58,7 +58,7 @@ func (k msgServer) AddX509Cert(goCtx context.Context, msg *types.MsgAddX509Cert) return nil, pkitypes.NewErrProvidedNotNocCertButExistingNoc(x509Certificate.Subject, x509Certificate.SubjectKeyID) } - if err = k.EnsureSenderAndOwnerVidMatch(ctx, existingCertificate, msg.Signer); err != nil { + if err = k.EnsureVidMatches(ctx, existingCertificate.Owner, msg.Signer); err != nil { return nil, err } } @@ -81,8 +81,8 @@ func (k msgServer) AddX509Cert(goCtx context.Context, msg *types.MsgAddX509Cert) return nil, pkitypes.NewErrProvidedNotNocCertButRootIsNoc() } - // Provided certificate, root certificate and account VID must match - if err = k.ensureCertsAndSenderVidMatch(ctx, rootCert, x509Certificate, signerAddr); err != nil { + // VID of account must match to VID of root and provided child certificates + if err = k.ensureVidMatches(ctx, rootCert, x509Certificate, signerAddr); err != nil { return nil, err } @@ -127,7 +127,7 @@ func (k msgServer) AddX509Cert(goCtx context.Context, msg *types.MsgAddX509Cert) return &types.MsgAddX509CertResponse{}, nil } -func (k msgServer) ensureCertsAndSenderVidMatch( +func (k msgServer) ensureVidMatches( ctx sdk.Context, rootCert *types.Certificate, childCert *x509.Certificate, diff --git a/x/pki/keeper/msg_server_remove_x_509_cert.go b/x/pki/keeper/msg_server_remove_x_509_cert.go index 49079b67e..0c8fefb46 100644 --- a/x/pki/keeper/msg_server_remove_x_509_cert.go +++ b/x/pki/keeper/msg_server_remove_x_509_cert.go @@ -20,7 +20,7 @@ func (k msgServer) RemoveX509Cert(goCtx context.Context, msg *types.MsgRemoveX50 // check if signer has vendor role if !k.dclauthKeeper.HasRole(ctx, signerAddr, dclauthtypes.Vendor) { - return nil, pkitypes.NewErrUnauthorizedRole("MsgAddNocX509RootCert", dclauthtypes.Vendor) + return nil, pkitypes.NewErrUnauthorizedRole("MsgRemoveX509Cert", dclauthtypes.Vendor) } aprCerts, foundApproved := k.GetApprovedCertificates(ctx, msg.Subject, msg.SubjectKeyId) @@ -35,7 +35,7 @@ func (k msgServer) RemoveX509Cert(goCtx context.Context, msg *types.MsgRemoveX50 return nil, pkitypes.NewErrMessageRemoveRoot(msg.Subject, msg.SubjectKeyId) } - if err := k.EnsureSenderAndOwnerVidMatch(ctx, certificates[0], msg.Signer); err != nil { + if err := k.EnsureVidMatches(ctx, certificates[0].Owner, msg.Signer); err != nil { return nil, err } diff --git a/x/pki/keeper/msg_server_revoke_x_509_cert.go b/x/pki/keeper/msg_server_revoke_x_509_cert.go index a83c5840f..a8c32e53b 100644 --- a/x/pki/keeper/msg_server_revoke_x_509_cert.go +++ b/x/pki/keeper/msg_server_revoke_x_509_cert.go @@ -19,7 +19,7 @@ func (k msgServer) RevokeX509Cert(goCtx context.Context, msg *types.MsgRevokeX50 // check if signer has vendor role if !k.dclauthKeeper.HasRole(ctx, signerAddr, dclauthtypes.Vendor) { - return nil, pkitypes.NewErrUnauthorizedRole("MsgAddNocX509RootCert", dclauthtypes.Vendor) + return nil, pkitypes.NewErrUnauthorizedRole("MsgRevokeX509Cert", dclauthtypes.Vendor) } certificates, _ := k.GetApprovedCertificates(ctx, msg.Subject, msg.SubjectKeyId) @@ -31,7 +31,7 @@ func (k msgServer) RevokeX509Cert(goCtx context.Context, msg *types.MsgRevokeX50 return nil, pkitypes.NewErrMessageRemoveRoot(msg.Subject, msg.SubjectKeyId) } - if err := k.EnsureSenderAndOwnerVidMatch(ctx, certificates.Certs[0], msg.Signer); err != nil { + if err := k.EnsureVidMatches(ctx, certificates.Certs[0].Owner, msg.Signer); err != nil { return nil, err }