-
Notifications
You must be signed in to change notification settings - Fork 45
/
Copy pathmsg_server_add_pki_revocation_distribution_point.go
146 lines (122 loc) · 5.55 KB
/
msg_server_add_pki_revocation_distribution_point.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
package keeper
import (
"context"
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"
)
func (k msgServer) AddPkiRevocationDistributionPoint(goCtx context.Context, msg *types.MsgAddPkiRevocationDistributionPoint) (*types.MsgAddPkiRevocationDistributionPointResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
// decode CrlSignerCertificate
crlSignerCertificate, err := x509.DecodeX509Certificate(msg.CrlSignerCertificate)
if err != nil {
return nil, pkitypes.NewErrInvalidCertificate(err)
}
// check if signer has vendor role
signerAddr, err := sdk.AccAddressFromBech32(msg.Signer)
if err != nil {
return nil, pkitypes.NewErrInvalidAddress(err)
}
signerAccount, _ := k.dclauthKeeper.GetAccountO(ctx, signerAddr)
if !k.dclauthKeeper.HasRole(ctx, signerAddr, dclauthtypes.Vendor) {
return nil, pkitypes.NewErrUnauthorizedRole("MsgAddPkiRevocationDistributionPoint", dclauthtypes.Vendor)
}
// compare VID in message and Vendor acount
if msg.Vid != signerAccount.VendorID {
return nil, pkitypes.NewErrMessageVidNotEqualAccountVid(msg.Vid, signerAccount.VendorID)
}
// check that distribution point doesn't exist yet
_, isFound := k.GetPkiRevocationDistributionPoint(ctx, msg.Vid, msg.Label, msg.IssuerSubjectKeyID)
if isFound {
return nil, pkitypes.NewErrPkiRevocationDistributionPointWithVidAndLabelAlreadyExists(msg.Vid, msg.Label, msg.IssuerSubjectKeyID)
}
if crlSignerCertificate.IsSelfSigned() {
// check that crlSignerCertificate cert is present on the ledger and has the same VID
err = k.checkRootCert(ctx, crlSignerCertificate, msg)
} else {
// check that crlSignerCertificate is chained back to a certificate on the ledger
err = k.checkCRLSignerNonRootCert(ctx, crlSignerCertificate, msg.CrlSignerDelegator, msg.IsPAA)
}
if err != nil {
return nil, err
}
revocationList, isFound := k.GetPkiRevocationDistributionPointsByIssuerSubjectKeyID(ctx, msg.IssuerSubjectKeyID)
if isFound {
for _, revocationPoint := range revocationList.Points {
if revocationPoint.DataURL == msg.DataURL && revocationPoint.Vid == msg.Vid {
return nil, pkitypes.NewErrPkiRevocationDistributionPointWithDataURLAlreadyExists(msg.DataURL, msg.IssuerSubjectKeyID)
}
}
}
// add to state
pkiRevocationDistributionPoint := types.PkiRevocationDistributionPoint{
Vid: msg.Vid,
Label: msg.Label,
IssuerSubjectKeyID: msg.IssuerSubjectKeyID,
Pid: msg.Pid,
IsPAA: msg.IsPAA,
CrlSignerCertificate: msg.CrlSignerCertificate,
CrlSignerDelegator: msg.CrlSignerDelegator,
DataURL: msg.DataURL,
DataFileSize: msg.DataFileSize,
DataDigest: msg.DataDigest,
DataDigestType: msg.DataDigestType,
RevocationType: msg.RevocationType,
SchemaVersion: msg.SchemaVersion,
}
k.SetPkiRevocationDistributionPoint(ctx, pkiRevocationDistributionPoint)
k.AddPkiRevocationDistributionPointBySubjectKeyID(ctx, pkiRevocationDistributionPoint)
return &types.MsgAddPkiRevocationDistributionPointResponse{}, nil
}
func (k msgServer) checkRootCert(ctx sdk.Context, crlSignerCertificate *x509.Certificate, msg *types.MsgAddPkiRevocationDistributionPoint) error {
// find the cert on the ledger
approvedCertificates, isFound := k.GetApprovedCertificates(ctx, crlSignerCertificate.Subject, crlSignerCertificate.SubjectKeyID)
if !isFound {
return pkitypes.NewErrRootCertificateDoesNotExist(crlSignerCertificate.Subject, crlSignerCertificate.SubjectKeyID)
}
// check that it has the same PEM value
var foundRootCert *types.Certificate
for _, approvedCertificate := range approvedCertificates.Certs {
if x509.RemoveWhitespaces(approvedCertificate.PemCert) == x509.RemoveWhitespaces(msg.CrlSignerCertificate) {
foundRootCert = approvedCertificate
break
}
}
if foundRootCert == nil {
return pkitypes.NewErrPemValuesNotEqual(crlSignerCertificate.Subject, crlSignerCertificate.SubjectKeyID)
}
// check that root cert has the same VID as in the message if it's non-VID scoped
// (vid-scoped has been already checked as patr of static validation + equality of PEM values
ledgerRootVid, err := x509.GetVidFromSubject(foundRootCert.SubjectAsText)
if err != nil {
return pkitypes.NewErrInvalidVidFormat(err)
}
if ledgerRootVid == 0 && msg.Vid != foundRootCert.Vid {
return pkitypes.NewErrMessageVidNotEqualRootCertVid(msg.Vid, foundRootCert.Vid)
}
return nil
}
func (k msgServer) checkCRLSignerNonRootCert(ctx sdk.Context, crlSignerCertificate *x509.Certificate, crlSignerDelegator string, isPAA bool) error {
if crlSignerDelegator != "" && !isPAA {
crlSignerDelegatorCert, err := x509.DecodeX509Certificate(crlSignerDelegator)
if err != nil {
return pkitypes.NewErrInvalidCertificate(err)
}
// verify CRL Signer certificate against Delegated PAI certificate
if err = crlSignerCertificate.Verify(crlSignerDelegatorCert, ctx.BlockTime()); err != nil {
return pkitypes.NewErrCRLSignerCertNotChainedBackToDelegator()
}
if _, err = k.verifyCertificate(ctx, crlSignerDelegatorCert); err != nil {
return pkitypes.NewErrCRLSignerCertDelegatorNotChainedBack()
}
return nil
}
// check that it's chained back to a cert on DCL
_, err := k.verifyCertificate(ctx, crlSignerCertificate)
if err != nil {
return pkitypes.NewErrCertNotChainedBack()
}
return nil
}