Implement delta CRL support

This commit provides real CRL support with persistent storage of CRLs as well
as support for delta CRLs using github.com/balacode/go-delta
This commit is contained in:
Jan Dittberner 2022-11-30 18:47:18 +01:00
parent 1031ee3118
commit 65c5bac2d9
10 changed files with 1023 additions and 75 deletions

View file

@ -85,7 +85,7 @@ func main() {
healthHandler := health.New(version, access) healthHandler := health.New(version, access)
revokingRepositories, err := configureRepositories(caConfig) revokingRepositories, err := configureRepositories(caConfig, logger)
if err != nil { if err != nil {
logger.WithError(err).Fatal("could not setup revoking repositories") logger.WithError(err).Fatal("could not setup revoking repositories")
} }
@ -117,20 +117,21 @@ func main() {
func configureRepositories( func configureRepositories(
caConfig *config.SignerConfig, caConfig *config.SignerConfig,
logger *logrus.Logger,
) (map[string]*revoking.X509Revoking, error) { ) (map[string]*revoking.X509Revoking, error) {
var err error var err error
result := make(map[string]*revoking.X509Revoking) result := make(map[string]*revoking.X509Revoking)
for _, name := range caConfig.RootCAs() { for _, name := range caConfig.RootCAs() {
result[fmt.Sprintf("root-%s", name)], err = buildX509Revoking(caConfig, name) result[fmt.Sprintf("root-%s", name)], err = buildX509Revoking(caConfig, name, logger)
if err != nil { if err != nil {
return nil, err return nil, err
} }
} }
for _, name := range caConfig.SubordinateCAs() { for _, name := range caConfig.SubordinateCAs() {
result[fmt.Sprintf("sub-%s", name)], err = buildX509Revoking(caConfig, name) result[fmt.Sprintf("sub-%s", name)], err = buildX509Revoking(caConfig, name, logger)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -139,7 +140,11 @@ func configureRepositories(
return result, nil return result, nil
} }
func buildX509Revoking(caConfig *config.SignerConfig, name string) (*revoking.X509Revoking, error) { func buildX509Revoking(
caConfig *config.SignerConfig,
name string,
logger *logrus.Logger,
) (*revoking.X509Revoking, error) {
caDef, err := caConfig.GetCADefinition(name) caDef, err := caConfig.GetCADefinition(name)
if err != nil { if err != nil {
return nil, fmt.Errorf("could not get CA definition for %s: %w", name, err) return nil, fmt.Errorf("could not get CA definition for %s: %w", name, err)
@ -155,6 +160,7 @@ func buildX509Revoking(caConfig *config.SignerConfig, name string) (*revoking.X5
caDef.KeyInfo.CRLSignatureAlgorithm, caDef.KeyInfo.CRLSignatureAlgorithm,
caDef.Certificate, caDef.Certificate,
caDef.KeyPair, caDef.KeyPair,
logger,
), nil ), nil
} }

2
go.mod
View file

@ -16,6 +16,8 @@ require (
) )
require ( require (
github.com/balacode/go-delta v0.1.0 // indirect
github.com/balacode/zr v1.0.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/miekg/pkcs11 v1.1.1 // indirect github.com/miekg/pkcs11 v1.1.1 // indirect
github.com/pkg/errors v0.9.1 // indirect github.com/pkg/errors v0.9.1 // indirect

4
go.sum
View file

@ -1,5 +1,9 @@
github.com/ThalesIgnite/crypto11 v1.2.5 h1:1IiIIEqYmBvUYFeMnHqRft4bwf/O36jryEUpY+9ef8E= github.com/ThalesIgnite/crypto11 v1.2.5 h1:1IiIIEqYmBvUYFeMnHqRft4bwf/O36jryEUpY+9ef8E=
github.com/ThalesIgnite/crypto11 v1.2.5/go.mod h1:ILDKtnCKiQ7zRoNxcp36Y1ZR8LBPmR2E23+wTQe/MlE= github.com/ThalesIgnite/crypto11 v1.2.5/go.mod h1:ILDKtnCKiQ7zRoNxcp36Y1ZR8LBPmR2E23+wTQe/MlE=
github.com/balacode/go-delta v0.1.0 h1:pwz4CMn06P2bIaIfAx3GSabMPwJp/Ww4if+7SgPYa3I=
github.com/balacode/go-delta v0.1.0/go.mod h1:wLNrwTI3lHbPBvnLzqbHmA7HVVlm1u22XLvhbeA6t3o=
github.com/balacode/zr v1.0.0 h1:MCupkEoXvrnCljc4KddiDOhR04ZLUAACgtKuo3o+9vc=
github.com/balacode/zr v1.0.0/go.mod h1:pLeSAL3DhZ9L0JuiRkUtIX3mLOCtzBLnDhfmykbSmkE=
github.com/dave/jennifer v1.4.1 h1:XyqG6cn5RQsTj3qlWQTKlRGAyrTcsk1kUmWdZBzRjDw= github.com/dave/jennifer v1.4.1 h1:XyqG6cn5RQsTj3qlWQTKlRGAyrTcsk1kUmWdZBzRjDw=
github.com/dave/jennifer v1.4.1/go.mod h1:7jEdnm+qBcxl8PC0zyp7vxcpSRnzXSt9r39tpTVGlwA= github.com/dave/jennifer v1.4.1/go.mod h1:7jEdnm+qBcxl8PC0zyp7vxcpSRnzXSt9r39tpTVGlwA=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=

View file

@ -20,6 +20,7 @@ package handler
import ( import (
"errors" "errors"
"fmt" "fmt"
"math/big"
"sync" "sync"
"time" "time"
@ -242,16 +243,31 @@ func (m *MsgPackHandler) handleHealthCommand() (*messages.HealthResponse, error)
} }
func (m *MsgPackHandler) handleFetchCRLCommand(command *messages.FetchCRLCommand) (*messages.FetchCRLResponse, error) { func (m *MsgPackHandler) handleFetchCRLCommand(command *messages.FetchCRLCommand) (*messages.FetchCRLResponse, error) {
res, err := m.fetchCRLHandler.FetchCRL(command.IssuerID) var crlNumber *big.Int
if command.LastKnownID != nil {
crlNumber = new(big.Int).SetBytes(command.LastKnownID)
}
res, err := m.fetchCRLHandler.FetchCRL(command.IssuerID, crlNumber)
if err != nil { if err != nil {
return nil, fmt.Errorf("could not fetch CRL: %w", err) return nil, fmt.Errorf("could not fetch CRL: %w", err)
} }
return &messages.FetchCRLResponse{ unchanged := crlNumber != nil && crlNumber.Cmp(res.Number) == 0
IsDelta: false,
CRLNumber: res.Number, response := &messages.FetchCRLResponse{
CRLData: res.CRLData, IssuerID: command.IssuerID,
}, nil IsDelta: res.IsDelta,
UnChanged: unchanged,
CRLNumber: res.Number.Bytes(),
}
if !unchanged {
response.CRLData = res.CRLData
}
return response, nil
} }
func New(logger *logrus.Logger, handlers ...RegisterHandler) (protocol.ServerHandler, error) { func New(logger *logrus.Logger, handlers ...RegisterHandler) (protocol.ServerHandler, error) {

View file

@ -27,6 +27,7 @@ import (
"math/big" "math/big"
"os" "os"
"path" "path"
"path/filepath"
"strings" "strings"
"sync" "sync"
"time" "time"
@ -96,6 +97,70 @@ type Repository struct {
crlNumberFileName string crlNumberFileName string
lock sync.Locker lock sync.Locker
entries []indexEntry entries []indexEntry
crlDirectory string
}
func (r *Repository) CleanUp() {
panic("implement me")
}
func (r *Repository) buildCRLFilename(b *big.Int) string {
number := fmt.Sprintf("%020x", b)
return path.Join(r.crlDirectory, number[:2], number[2:4], fmt.Sprintf("%s.crl", number[4:]))
}
func (r *Repository) currentCRLLink() string {
return path.Join(r.crlDirectory, "current.crl")
}
func (r *Repository) LoadCRL(b *big.Int) ([]byte, error) {
var crlFileName string
if b == nil {
crlFileName = r.currentCRLLink()
} else {
crlFileName = r.buildCRLFilename(b)
}
crlData, err := os.ReadFile(crlFileName)
if err != nil {
return nil, fmt.Errorf("could not read CRL from %s: %w", crlFileName, err)
}
return crlData, nil
}
func (r *Repository) StoreCRL(b *big.Int, bytes []byte) error {
if b == nil {
return errors.New("crl number must not be nil")
}
crlFilename := r.buildCRLFilename(b)
err := os.MkdirAll(path.Dir(crlFilename), 0o700)
if err != nil {
return fmt.Errorf("could not create directory hierarchy for %s: %w", crlFilename, err)
}
err = os.WriteFile(crlFilename, bytes, 0o600)
if err != nil {
return fmt.Errorf("could not write CRL to %s: %w", crlFilename, err)
}
crlLink := r.currentCRLLink()
if err = os.Remove(crlLink); err != nil {
if !os.IsNotExist(err) {
return fmt.Errorf("could not remove CRL symlink %s: %w", crlLink, err)
}
}
if err = os.Symlink(crlFilename, crlLink); err != nil {
return fmt.Errorf("could not create CRL symlink from %s to %s: %w", crlFilename, crlLink, err)
}
return nil
} }
func (r *Repository) NextCRLNumber() (*big.Int, error) { func (r *Repository) NextCRLNumber() (*big.Int, error) {
@ -420,15 +485,21 @@ func NewFileRepository(baseDirectory string) (*Repository, error) {
return nil, fmt.Errorf("could not change to base directory %s: %w", baseDirectory, err) return nil, fmt.Errorf("could not change to base directory %s: %w", baseDirectory, err)
} }
err = os.MkdirAll(baseDirectory, 0750) //nolint:gomnd err = os.MkdirAll(baseDirectory, 0o750) //nolint:gomnd
if err != nil { if err != nil {
return nil, fmt.Errorf("could not create base directory %s: %w", baseDirectory, err) return nil, fmt.Errorf("could not create base directory %s: %w", baseDirectory, err)
} }
} }
baseDirectory, err = filepath.Abs(baseDirectory)
if err != nil {
return nil, fmt.Errorf("could not get absolute name for %s: %w", baseDirectory, err)
}
return &Repository{ return &Repository{
indexFileName: path.Join(baseDirectory, "index.txt"), indexFileName: path.Join(baseDirectory, "index.txt"),
crlNumberFileName: path.Join(baseDirectory, "crlnumber"), crlNumberFileName: path.Join(baseDirectory, "crlnumber"),
crlDirectory: path.Join(baseDirectory, "crls"),
lock: &sync.Mutex{}, lock: &sync.Mutex{},
}, nil }, nil
} }

View file

@ -26,6 +26,9 @@ import (
type Repository interface { type Repository interface {
// StoreRevocation stores information about a revoked certificate. // StoreRevocation stores information about a revoked certificate.
StoreRevocation(*pkix.RevokedCertificate) error StoreRevocation(*pkix.RevokedCertificate) error
LoadCRL(*big.Int) ([]byte, error)
StoreCRL(*big.Int, []byte) error
RevokedCertificates() ([]pkix.RevokedCertificate, error) RevokedCertificates() ([]pkix.RevokedCertificate, error)
NextCRLNumber() (*big.Int, error) NextCRLNumber() (*big.Int, error)
CleanUp()
} }

View file

@ -28,6 +28,9 @@ import (
"math/big" "math/big"
"strings" "strings"
"time" "time"
"github.com/balacode/go-delta"
"github.com/sirupsen/logrus"
) )
var OidCRLReason = asn1.ObjectIdentifier{2, 5, 29, 21} var OidCRLReason = asn1.ObjectIdentifier{2, 5, 29, 21}
@ -93,6 +96,7 @@ type X509Revoking struct {
crlAlgorithm x509.SignatureAlgorithm crlAlgorithm x509.SignatureAlgorithm
crlIssuer *x509.Certificate crlIssuer *x509.Certificate
signer crypto.Signer signer crypto.Signer
logger *logrus.Logger
} }
type RevokeCertificate struct { type RevokeCertificate struct {
@ -108,8 +112,9 @@ func NewRevokeCertificate(serialNumber *big.Int, reason CRLReason) *RevokeCertif
} }
type CRLInformation struct { type CRLInformation struct {
CRL []byte // DER encoded CRL CRL []byte // DER encoded CRL
Number *big.Int Number *big.Int
NextUpdate time.Time
} }
func (r *X509Revoking) Revoke(revokeCertificate *RevokeCertificate) (*pkix.RevokedCertificate, error) { func (r *X509Revoking) Revoke(revokeCertificate *RevokeCertificate) (*pkix.RevokedCertificate, error) {
@ -126,7 +131,7 @@ func (r *X509Revoking) Revoke(revokeCertificate *RevokeCertificate) (*pkix.Revok
return revoked, nil return revoked, nil
} }
func (r *X509Revoking) CreateCRL() (*CRLInformation, error) { func (r *X509Revoking) createCRL() (*CRLInformation, error) {
revoked, err := r.repository.RevokedCertificates() revoked, err := r.repository.RevokedCertificates()
if err != nil { if err != nil {
return nil, fmt.Errorf("could not get revocation information: %w", err) return nil, fmt.Errorf("could not get revocation information: %w", err)
@ -137,17 +142,63 @@ func (r *X509Revoking) CreateCRL() (*CRLInformation, error) {
return nil, fmt.Errorf("could not get next CRL number: %w", err) return nil, fmt.Errorf("could not get next CRL number: %w", err)
} }
nextUpdate := time.Now().UTC().Add(defaultCRLValidity)
list, err := x509.CreateRevocationList(rand.Reader, &x509.RevocationList{ list, err := x509.CreateRevocationList(rand.Reader, &x509.RevocationList{
SignatureAlgorithm: r.crlAlgorithm, SignatureAlgorithm: r.crlAlgorithm,
RevokedCertificates: revoked, RevokedCertificates: revoked,
Number: nextNumber, Number: nextNumber,
NextUpdate: time.Now().UTC().Add(defaultCRLValidity), ThisUpdate: time.Now().UTC(),
NextUpdate: nextUpdate,
}, r.crlIssuer, r.signer) }, r.crlIssuer, r.signer)
if err != nil { if err != nil {
return nil, fmt.Errorf("could not sign revocation list: %w", err) return nil, fmt.Errorf("could not sign revocation list: %w", err)
} }
return &CRLInformation{CRL: list, Number: nextNumber}, nil err = r.repository.StoreCRL(nextNumber, list)
if err != nil {
return nil, fmt.Errorf("could not store new CRL: %w", err)
}
return &CRLInformation{CRL: list, Number: nextNumber, NextUpdate: nextUpdate}, nil
}
func (r *X509Revoking) GetCurrentCRL() (*CRLInformation, error) {
return r.GetCRL(nil)
}
const maximumCRLLifetime = 6 * time.Hour
func (r *X509Revoking) GetCRL(number *big.Int) (*CRLInformation, error) {
var (
crl []byte
err error
list *x509.RevocationList
)
crl, err = r.repository.LoadCRL(number)
if err != nil {
r.logger.WithError(err).Warn("could not load CRL")
if number != nil {
return nil, fmt.Errorf("could not load crl number 0x%0x", number)
}
}
if crl != nil {
list, err = x509.ParseRevocationList(crl)
if err != nil {
r.logger.WithError(err).Warn("could not parse CRL")
}
stillValid := list.ThisUpdate.Add(maximumCRLLifetime).After(time.Now().UTC())
if number != nil || stillValid {
return &CRLInformation{CRL: crl, Number: list.Number, NextUpdate: list.NextUpdate}, nil
}
}
return r.createCRL()
} }
func NewX509Revoking( func NewX509Revoking(
@ -155,12 +206,20 @@ func NewX509Revoking(
crlAlgorithm x509.SignatureAlgorithm, crlAlgorithm x509.SignatureAlgorithm,
issuer *x509.Certificate, issuer *x509.Certificate,
signer crypto.Signer, signer crypto.Signer,
logger *logrus.Logger,
) *X509Revoking { ) *X509Revoking {
return &X509Revoking{repository: repo, crlAlgorithm: crlAlgorithm, crlIssuer: issuer, signer: signer} return &X509Revoking{
repository: repo,
crlAlgorithm: crlAlgorithm,
crlIssuer: issuer,
signer: signer,
logger: logger,
}
} }
type Result struct { type Result struct {
CRLData []byte CRLData []byte
IsDelta bool
Number *big.Int Number *big.Int
} }
@ -172,16 +231,45 @@ func NewFetchCRLHandler(repositories map[string]*X509Revoking) *FetchCRLHandler
return &FetchCRLHandler{repositories: repositories} return &FetchCRLHandler{repositories: repositories}
} }
func (h *FetchCRLHandler) FetchCRL(issuerID string) (*Result, error) { func (h *FetchCRLHandler) FetchCRL(issuerID string, crlNumber *big.Int) (*Result, error) {
var (
currentCRL, oldCRL *CRLInformation
err error
)
repo, ok := h.repositories[issuerID] repo, ok := h.repositories[issuerID]
if !ok { if !ok {
return nil, fmt.Errorf("unknown issuer ID %s", issuerID) return nil, fmt.Errorf("unknown issuer ID %s", issuerID)
} }
currentCRL, err := repo.CreateCRL() if repo.signer == nil {
if err != nil { return nil, fmt.Errorf("key for issuer ID %s is not available", issuerID)
return nil, fmt.Errorf("could not create CRL for issuer ID %s: %w", issuerID, err)
} }
return &Result{CRLData: currentCRL.CRL, Number: currentCRL.Number}, nil currentCRL, err = repo.GetCurrentCRL()
if err != nil {
return nil, fmt.Errorf("could not get CRL for issuer ID %s: %w", issuerID, err)
}
if crlNumber == nil {
return &Result{CRLData: currentCRL.CRL, Number: currentCRL.Number, IsDelta: false}, nil
}
if crlNumber.Cmp(currentCRL.Number) == 0 {
return &Result{CRLData: nil, Number: currentCRL.Number, IsDelta: false}, nil
}
oldCRL, err = repo.GetCRL(crlNumber)
if err != nil {
return &Result{CRLData: currentCRL.CRL, Number: currentCRL.Number, IsDelta: false}, nil
}
diff := delta.Make(oldCRL.CRL, currentCRL.CRL)
patchBytes := diff.Bytes()
if len(patchBytes) > len(currentCRL.CRL) {
return &Result{CRLData: currentCRL.CRL, Number: currentCRL.Number, IsDelta: false}, nil
}
return &Result{CRLData: patchBytes, Number: currentCRL.Number, IsDelta: true}, nil
} }

View file

@ -18,6 +18,7 @@ limitations under the License.
package revoking_test package revoking_test
import ( import (
"bytes"
"crypto/rand" "crypto/rand"
"crypto/rsa" "crypto/rsa"
"crypto/x509" "crypto/x509"
@ -28,6 +29,7 @@ import (
"math/big" "math/big"
"testing" "testing"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -49,9 +51,36 @@ func randomSerial(t *testing.T) *big.Int {
type testRepo struct { type testRepo struct {
crlNumber *big.Int crlNumber *big.Int
crls map[string][]byte
current string
revoked []pkix.RevokedCertificate revoked []pkix.RevokedCertificate
} }
func (t *testRepo) LoadCRL(b *big.Int) ([]byte, error) {
var key string
if b == nil {
key = t.current
} else {
key = b.String()
}
crl, ok := t.crls[key]
if !ok {
return nil, errors.New("no CRL for you")
}
return crl, nil
}
func (t *testRepo) StoreCRL(b *big.Int, crl []byte) error {
t.crls[b.String()] = crl
return nil
}
func (t *testRepo) CleanUp() {}
func (t *testRepo) NextCRLNumber() (*big.Int, error) { func (t *testRepo) NextCRLNumber() (*big.Int, error) {
newNumber := new(big.Int).Add(t.crlNumber, big.NewInt(1)) newNumber := new(big.Int).Add(t.crlNumber, big.NewInt(1))
@ -74,7 +103,9 @@ func (t *testRepo) StoreRevocation(revoked *pkix.RevokedCertificate) error {
return nil return nil
} }
type brokenRepo struct{} type brokenRepo struct {
noStoreRepo
}
func (r *brokenRepo) NextCRLNumber() (*big.Int, error) { func (r *brokenRepo) NextCRLNumber() (*big.Int, error) {
return nil, errors.New("don't know") return nil, errors.New("don't know")
@ -88,14 +119,28 @@ func (*brokenRepo) StoreRevocation(_ *pkix.RevokedCertificate) error {
return errors.New("cannot store") return errors.New("cannot store")
} }
type brokenRepoNoCrlNumber struct { type noStoreRepo struct{}
}
func (b brokenRepoNoCrlNumber) StoreRevocation(_ *pkix.RevokedCertificate) error { func (r noStoreRepo) StoreRevocation(_ *pkix.RevokedCertificate) error {
// do nothing // do nothing
return nil return nil
} }
type brokenRepoNoCrlNumber struct {
noStoreRepo
}
func (r noStoreRepo) LoadCRL(_ *big.Int) ([]byte, error) {
return nil, errors.New("no CRL")
}
func (r noStoreRepo) StoreCRL(_ *big.Int, _ []byte) error {
// do nothing
return nil
}
func (r noStoreRepo) CleanUp() {}
func (b brokenRepoNoCrlNumber) RevokedCertificates() ([]pkix.RevokedCertificate, error) { func (b brokenRepoNoCrlNumber) RevokedCertificates() ([]pkix.RevokedCertificate, error) {
return make([]pkix.RevokedCertificate, 0), nil return make([]pkix.RevokedCertificate, 0), nil
} }
@ -105,11 +150,7 @@ func (b brokenRepoNoCrlNumber) NextCRLNumber() (*big.Int, error) {
} }
type brokenRepoNoRevocations struct { type brokenRepoNoRevocations struct {
} noStoreRepo
func (b brokenRepoNoRevocations) StoreRevocation(_ *pkix.RevokedCertificate) error {
// do nothing
return nil
} }
func (b brokenRepoNoRevocations) RevokedCertificates() ([]pkix.RevokedCertificate, error) { func (b brokenRepoNoRevocations) RevokedCertificates() ([]pkix.RevokedCertificate, error) {
@ -121,11 +162,18 @@ func (b brokenRepoNoRevocations) NextCRLNumber() (*big.Int, error) {
} }
func TestX509Revoking_Revoke(t *testing.T) { func TestX509Revoking_Revoke(t *testing.T) {
testRepository := testRepo{revoked: make([]pkix.RevokedCertificate, 0), crlNumber: big.NewInt(0)} testRepository := testRepo{
revoked: make([]pkix.RevokedCertificate, 0),
crlNumber: big.NewInt(0),
crls: map[string][]byte{},
}
caKey, caCertificate := prepareTestCA(t) caKey, caCertificate := prepareTestCA(t)
r := revoking.NewX509Revoking(&testRepository, x509.ECDSAWithSHA256, caCertificate, caKey) logger := logrus.New()
logger.SetOutput(&bytes.Buffer{})
r := revoking.NewX509Revoking(&testRepository, x509.ECDSAWithSHA256, caCertificate, caKey, logger)
serial := randomSerial(t) serial := randomSerial(t)
@ -149,7 +197,10 @@ func TestX509Revoking_Revoke(t *testing.T) {
func TestX509Revoking_Revoke_BrokenRepo(t *testing.T) { func TestX509Revoking_Revoke_BrokenRepo(t *testing.T) {
caKey, caCertificate := prepareTestCA(t) caKey, caCertificate := prepareTestCA(t)
r := revoking.NewX509Revoking(&brokenRepo{}, x509.SHA256WithRSA, caCertificate, caKey) logger := logrus.New()
logger.SetOutput(&bytes.Buffer{})
r := revoking.NewX509Revoking(&brokenRepo{}, x509.SHA256WithRSA, caCertificate, caKey, logger)
serial := randomSerial(t) serial := randomSerial(t)
@ -163,11 +214,12 @@ func TestX509Revoking_Revoke_BrokenRepo(t *testing.T) {
func TestX509Revoking_CreateCRL(t *testing.T) { func TestX509Revoking_CreateCRL(t *testing.T) {
key, certificate := prepareTestCA(t) key, certificate := prepareTestCA(t)
logger := logrus.New()
logger.SetOutput(&bytes.Buffer{})
r := revoking.NewX509Revoking( r := revoking.NewX509Revoking(
&testRepo{revoked: make([]pkix.RevokedCertificate, 0), crlNumber: big.NewInt(0)}, &testRepo{revoked: make([]pkix.RevokedCertificate, 0), crlNumber: big.NewInt(0), crls: map[string][]byte{}},
x509.SHA256WithRSA, x509.SHA256WithRSA, certificate, key, logger,
certificate,
key,
) )
serial := randomSerial(t) serial := randomSerial(t)
@ -175,7 +227,7 @@ func TestX509Revoking_CreateCRL(t *testing.T) {
_, err := r.Revoke(revoking.NewRevokeCertificate(serial, revoking.CRLReasonKeyCompromise)) _, err := r.Revoke(revoking.NewRevokeCertificate(serial, revoking.CRLReasonKeyCompromise))
require.NoError(t, err) require.NoError(t, err)
crl, err := r.CreateCRL() crl, err := r.GetCRL(nil)
assert.NoError(t, err) assert.NoError(t, err)
assert.NotNil(t, crl) assert.NotNil(t, crl)
@ -200,48 +252,55 @@ func TestX509Revoking_CreateCRL(t *testing.T) {
assert.True(t, found) assert.True(t, found)
} }
func TestX509Revoking_CreateCRL_BrokenRepoNoRevocations(t *testing.T) { func TestX509Revoking_GetCRL_BrokenRepoNoRevocations(t *testing.T) {
caKey, caCertificate := prepareTestCA(t) caKey, caCertificate := prepareTestCA(t)
r := revoking.NewX509Revoking(&brokenRepoNoRevocations{}, x509.SHA256WithRSA, caCertificate, caKey) logger := logrus.New()
logger.SetOutput(&bytes.Buffer{})
r := revoking.NewX509Revoking(&brokenRepoNoRevocations{}, x509.SHA256WithRSA, caCertificate, caKey, logger)
serial := randomSerial(t) serial := randomSerial(t)
_, err := r.Revoke(revoking.NewRevokeCertificate(serial, revoking.CRLReasonKeyCompromise)) _, err := r.Revoke(revoking.NewRevokeCertificate(serial, revoking.CRLReasonKeyCompromise))
require.NoError(t, err) require.NoError(t, err)
crl, err := r.CreateCRL() crl, err := r.GetCRL(nil)
assert.Error(t, err) assert.Error(t, err)
assert.ErrorContains(t, err, "could not get revocation information") assert.ErrorContains(t, err, "could not get revocation information")
assert.Nil(t, crl) assert.Nil(t, crl)
} }
func TestX509Revoking_CreateCRL_BrokenRepoNoCRLNumber(t *testing.T) { func TestX509Revoking_GetCRL_BrokenRepoNoCRLNumber(t *testing.T) {
caKey, caCertificate := prepareTestCA(t) caKey, caCertificate := prepareTestCA(t)
r := revoking.NewX509Revoking(&brokenRepoNoCrlNumber{}, x509.SHA256WithRSA, caCertificate, caKey) logger := logrus.New()
logger.SetOutput(&bytes.Buffer{})
r := revoking.NewX509Revoking(&brokenRepoNoCrlNumber{}, x509.SHA256WithRSA, caCertificate, caKey, logger)
serial := randomSerial(t) serial := randomSerial(t)
_, err := r.Revoke(revoking.NewRevokeCertificate(serial, revoking.CRLReasonKeyCompromise)) _, err := r.Revoke(revoking.NewRevokeCertificate(serial, revoking.CRLReasonKeyCompromise))
require.NoError(t, err) require.NoError(t, err)
crl, err := r.CreateCRL() crl, err := r.GetCRL(nil)
assert.Error(t, err) assert.Error(t, err)
assert.ErrorContains(t, err, "could not get next CRL number") assert.ErrorContains(t, err, "could not get next CRL number")
assert.Nil(t, crl) assert.Nil(t, crl)
} }
func TestX509Revoking_CreateCRL_WrongAlgorithm(t *testing.T) { func TestX509Revoking_GetCRL_WrongAlgorithm(t *testing.T) {
key, certificate := prepareTestCA(t) key, certificate := prepareTestCA(t)
logger := logrus.New()
logger.SetOutput(&bytes.Buffer{})
r := revoking.NewX509Revoking( r := revoking.NewX509Revoking(
&testRepo{revoked: make([]pkix.RevokedCertificate, 0), crlNumber: big.NewInt(0)}, &testRepo{revoked: make([]pkix.RevokedCertificate, 0), crlNumber: big.NewInt(0), crls: map[string][]byte{}},
x509.ECDSAWithSHA256, x509.ECDSAWithSHA256, certificate, key, logger,
certificate,
key,
) )
serial := randomSerial(t) serial := randomSerial(t)
@ -249,7 +308,7 @@ func TestX509Revoking_CreateCRL_WrongAlgorithm(t *testing.T) {
_, err := r.Revoke(revoking.NewRevokeCertificate(serial, revoking.CRLReasonKeyCompromise)) _, err := r.Revoke(revoking.NewRevokeCertificate(serial, revoking.CRLReasonKeyCompromise))
require.NoError(t, err) require.NoError(t, err)
crl, err := r.CreateCRL() crl, err := r.GetCRL(nil)
assert.Error(t, err) assert.Error(t, err)
assert.ErrorContains(t, err, "could not sign revocation list") assert.ErrorContains(t, err, "could not sign revocation list")

View file

@ -102,8 +102,8 @@ func (r *ResponseAnnounce) String() string {
} }
type FetchCRLCommand struct { type FetchCRLCommand struct {
IssuerID string `msgpack:"issuer_id"` IssuerID string `msgpack:"issuer_id"`
LastKnownID *big.Int `msgpack:"last_known_id"` LastKnownID []byte `msgpack:"last_known_id"`
} }
func (f *FetchCRLCommand) String() string { func (f *FetchCRLCommand) String() string {
@ -112,7 +112,7 @@ func (f *FetchCRLCommand) String() string {
_, _ = fmt.Fprintf(builder, "issuerId='%s'", f.IssuerID) _, _ = fmt.Fprintf(builder, "issuerId='%s'", f.IssuerID)
if f.LastKnownID != nil { if f.LastKnownID != nil {
_, _ = fmt.Fprintf(builder, ", lastKnownId=%s", f.LastKnownID.Text(16)) _, _ = fmt.Fprintf(builder, ", lastKnownId=0x%s", new(big.Int).SetBytes(f.LastKnownID).Text(16))
} }
return builder.String() return builder.String()
@ -226,38 +226,54 @@ func (h *HealthResponse) String() string {
type FetchCRLResponse struct { type FetchCRLResponse struct {
IssuerID string `msgpack:"issuer_id"` IssuerID string `msgpack:"issuer_id"`
IsDelta bool `msgpack:"is_delta"` IsDelta bool `msgpack:"is_delta"`
UnChanged bool `msgpack:"unchanged"`
CRLData []byte `msgpack:"crl_data"` CRLData []byte `msgpack:"crl_data"`
CRLNumber *big.Int CRLNumber []byte `msgpack:"crl_number"`
} }
func (r *FetchCRLResponse) String() string { func (r *FetchCRLResponse) String() string {
builder := &strings.Builder{} builder := &strings.Builder{}
_, _ = fmt.Fprintf(builder, "issuer id=%s, delta CRL data=%v", r.IssuerID, r.IsDelta) _, _ = fmt.Fprintf(
builder,
"issuer id=%s, delta CRL data=%t, unchanged=%t, CRL number=0x%s",
r.IssuerID,
r.IsDelta,
r.UnChanged,
new(big.Int).SetBytes(r.CRLNumber).Text(16),
)
if r.UnChanged {
return builder.String()
}
if r.IsDelta { if r.IsDelta {
_, _ = fmt.Fprint(builder, ", delta CRL data not shown") _, _ = fmt.Fprint(builder, ", delta CRL data not shown")
} else {
revocationList, err := x509.ParseRevocationList(r.CRLData) return builder.String()
if err != nil {
_, _ = fmt.Fprintf(builder, ", could not parse CRL: %s", err.Error())
} else {
_, _ = fmt.Fprintf(
builder,
", CRL info: issuer=%s, number=%s, next update=%s, revoked certificates=%d",
revocationList.Issuer,
revocationList.Number,
revocationList.NextUpdate,
len(revocationList.RevokedCertificates),
)
_, _ = builder.WriteString(", CRL data:\n")
_ = pem.Encode(builder, &pem.Block{
Type: "CERTIFICATE REVOCATION LIST",
Bytes: r.CRLData,
})
}
} }
revocationList, err := x509.ParseRevocationList(r.CRLData)
if err != nil {
_, _ = fmt.Fprintf(builder, ", could not parse CRL: %s", err.Error())
return builder.String()
}
_, _ = fmt.Fprintf(
builder,
", CRL info: issuer=%s, number=0x%s, next update=%s, revoked certificates=%d",
revocationList.Issuer,
revocationList.Number.Text(16),
revocationList.NextUpdate,
len(revocationList.RevokedCertificates),
)
_, _ = builder.WriteString(", CRL data:\n")
_ = pem.Encode(builder, &pem.Block{
Type: "CERTIFICATE REVOCATION LIST",
Bytes: r.CRLData,
})
return builder.String() return builder.String()
} }

View file

@ -26,6 +26,36 @@ func ___encode(i interface{}) ([]byte, error) {
// encodeAsArray // encodeAsArray
func ___encodeAsArray(i interface{}) ([]byte, error) { func ___encodeAsArray(i interface{}) ([]byte, error) {
switch v := i.(type) { switch v := i.(type) {
case FetchCRLCommand:
encoder := enc.NewEncoder()
size, err := ___calcArraySizeFetchCRLCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, encoder)
if err != nil {
return nil, err
}
encoder.MakeBytes(size)
b, offset, err := ___encodeArrayFetchCRLCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, encoder, 0)
if err != nil {
return nil, err
}
if size != offset {
return nil, fmt.Errorf("%s size / offset different %d : %d", "FetchCRLCommand", size, offset)
}
return b, err
case *FetchCRLCommand:
encoder := enc.NewEncoder()
size, err := ___calcArraySizeFetchCRLCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(*v, encoder)
if err != nil {
return nil, err
}
encoder.MakeBytes(size)
b, offset, err := ___encodeArrayFetchCRLCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(*v, encoder, 0)
if err != nil {
return nil, err
}
if size != offset {
return nil, fmt.Errorf("%s size / offset different %d : %d", "FetchCRLCommand", size, offset)
}
return b, err
case HealthCommand: case HealthCommand:
encoder := enc.NewEncoder() encoder := enc.NewEncoder()
size, err := ___calcArraySizeHealthCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, encoder) size, err := ___calcArraySizeHealthCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, encoder)
@ -116,6 +146,36 @@ func ___encodeAsArray(i interface{}) ([]byte, error) {
return nil, fmt.Errorf("%s size / offset different %d : %d", "HealthResponse", size, offset) return nil, fmt.Errorf("%s size / offset different %d : %d", "HealthResponse", size, offset)
} }
return b, err return b, err
case FetchCRLResponse:
encoder := enc.NewEncoder()
size, err := ___calcArraySizeFetchCRLResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, encoder)
if err != nil {
return nil, err
}
encoder.MakeBytes(size)
b, offset, err := ___encodeArrayFetchCRLResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, encoder, 0)
if err != nil {
return nil, err
}
if size != offset {
return nil, fmt.Errorf("%s size / offset different %d : %d", "FetchCRLResponse", size, offset)
}
return b, err
case *FetchCRLResponse:
encoder := enc.NewEncoder()
size, err := ___calcArraySizeFetchCRLResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(*v, encoder)
if err != nil {
return nil, err
}
encoder.MakeBytes(size)
b, offset, err := ___encodeArrayFetchCRLResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(*v, encoder, 0)
if err != nil {
return nil, err
}
if size != offset {
return nil, fmt.Errorf("%s size / offset different %d : %d", "FetchCRLResponse", size, offset)
}
return b, err
case ErrorResponse: case ErrorResponse:
encoder := enc.NewEncoder() encoder := enc.NewEncoder()
size, err := ___calcArraySizeErrorResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, encoder) size, err := ___calcArraySizeErrorResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, encoder)
@ -153,6 +213,36 @@ func ___encodeAsArray(i interface{}) ([]byte, error) {
// encodeAsMap // encodeAsMap
func ___encodeAsMap(i interface{}) ([]byte, error) { func ___encodeAsMap(i interface{}) ([]byte, error) {
switch v := i.(type) { switch v := i.(type) {
case FetchCRLCommand:
encoder := enc.NewEncoder()
size, err := ___calcMapSizeFetchCRLCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, encoder)
if err != nil {
return nil, err
}
encoder.MakeBytes(size)
b, offset, err := ___encodeMapFetchCRLCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, encoder, 0)
if err != nil {
return nil, err
}
if size != offset {
return nil, fmt.Errorf("%s size / offset different %d : %d", "FetchCRLCommand", size, offset)
}
return b, err
case *FetchCRLCommand:
encoder := enc.NewEncoder()
size, err := ___calcMapSizeFetchCRLCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(*v, encoder)
if err != nil {
return nil, err
}
encoder.MakeBytes(size)
b, offset, err := ___encodeMapFetchCRLCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(*v, encoder, 0)
if err != nil {
return nil, err
}
if size != offset {
return nil, fmt.Errorf("%s size / offset different %d : %d", "FetchCRLCommand", size, offset)
}
return b, err
case HealthCommand: case HealthCommand:
encoder := enc.NewEncoder() encoder := enc.NewEncoder()
size, err := ___calcMapSizeHealthCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, encoder) size, err := ___calcMapSizeHealthCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, encoder)
@ -243,6 +333,36 @@ func ___encodeAsMap(i interface{}) ([]byte, error) {
return nil, fmt.Errorf("%s size / offset different %d : %d", "HealthResponse", size, offset) return nil, fmt.Errorf("%s size / offset different %d : %d", "HealthResponse", size, offset)
} }
return b, err return b, err
case FetchCRLResponse:
encoder := enc.NewEncoder()
size, err := ___calcMapSizeFetchCRLResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, encoder)
if err != nil {
return nil, err
}
encoder.MakeBytes(size)
b, offset, err := ___encodeMapFetchCRLResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, encoder, 0)
if err != nil {
return nil, err
}
if size != offset {
return nil, fmt.Errorf("%s size / offset different %d : %d", "FetchCRLResponse", size, offset)
}
return b, err
case *FetchCRLResponse:
encoder := enc.NewEncoder()
size, err := ___calcMapSizeFetchCRLResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(*v, encoder)
if err != nil {
return nil, err
}
encoder.MakeBytes(size)
b, offset, err := ___encodeMapFetchCRLResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(*v, encoder, 0)
if err != nil {
return nil, err
}
if size != offset {
return nil, fmt.Errorf("%s size / offset different %d : %d", "FetchCRLResponse", size, offset)
}
return b, err
case ErrorResponse: case ErrorResponse:
encoder := enc.NewEncoder() encoder := enc.NewEncoder()
size, err := ___calcMapSizeErrorResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, encoder) size, err := ___calcMapSizeErrorResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, encoder)
@ -289,6 +409,20 @@ func ___decode(data []byte, i interface{}) (bool, error) {
// decodeAsArray // decodeAsArray
func ___decodeAsArray(data []byte, i interface{}) (bool, error) { func ___decodeAsArray(data []byte, i interface{}) (bool, error) {
switch v := i.(type) { switch v := i.(type) {
case *FetchCRLCommand:
decoder := dec.NewDecoder(data)
offset, err := ___decodeArrayFetchCRLCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, decoder, 0)
if err == nil && offset != decoder.Len() {
return true, fmt.Errorf("read length is different [%d] [%d] ", offset, decoder.Len())
}
return true, err
case **FetchCRLCommand:
decoder := dec.NewDecoder(data)
offset, err := ___decodeArrayFetchCRLCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(*v, decoder, 0)
if err == nil && offset != decoder.Len() {
return true, fmt.Errorf("read length is different [%d] [%d] ", offset, decoder.Len())
}
return true, err
case *HealthCommand: case *HealthCommand:
decoder := dec.NewDecoder(data) decoder := dec.NewDecoder(data)
offset, err := ___decodeArrayHealthCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, decoder, 0) offset, err := ___decodeArrayHealthCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, decoder, 0)
@ -331,6 +465,20 @@ func ___decodeAsArray(data []byte, i interface{}) (bool, error) {
return true, fmt.Errorf("read length is different [%d] [%d] ", offset, decoder.Len()) return true, fmt.Errorf("read length is different [%d] [%d] ", offset, decoder.Len())
} }
return true, err return true, err
case *FetchCRLResponse:
decoder := dec.NewDecoder(data)
offset, err := ___decodeArrayFetchCRLResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, decoder, 0)
if err == nil && offset != decoder.Len() {
return true, fmt.Errorf("read length is different [%d] [%d] ", offset, decoder.Len())
}
return true, err
case **FetchCRLResponse:
decoder := dec.NewDecoder(data)
offset, err := ___decodeArrayFetchCRLResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(*v, decoder, 0)
if err == nil && offset != decoder.Len() {
return true, fmt.Errorf("read length is different [%d] [%d] ", offset, decoder.Len())
}
return true, err
case *ErrorResponse: case *ErrorResponse:
decoder := dec.NewDecoder(data) decoder := dec.NewDecoder(data)
offset, err := ___decodeArrayErrorResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, decoder, 0) offset, err := ___decodeArrayErrorResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, decoder, 0)
@ -352,6 +500,20 @@ func ___decodeAsArray(data []byte, i interface{}) (bool, error) {
// decodeAsMap // decodeAsMap
func ___decodeAsMap(data []byte, i interface{}) (bool, error) { func ___decodeAsMap(data []byte, i interface{}) (bool, error) {
switch v := i.(type) { switch v := i.(type) {
case *FetchCRLCommand:
decoder := dec.NewDecoder(data)
offset, err := ___decodeMapFetchCRLCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, decoder, 0)
if err == nil && offset != decoder.Len() {
return true, fmt.Errorf("read length is different [%d] [%d] ", offset, decoder.Len())
}
return true, err
case **FetchCRLCommand:
decoder := dec.NewDecoder(data)
offset, err := ___decodeMapFetchCRLCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(*v, decoder, 0)
if err == nil && offset != decoder.Len() {
return true, fmt.Errorf("read length is different [%d] [%d] ", offset, decoder.Len())
}
return true, err
case *HealthCommand: case *HealthCommand:
decoder := dec.NewDecoder(data) decoder := dec.NewDecoder(data)
offset, err := ___decodeMapHealthCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, decoder, 0) offset, err := ___decodeMapHealthCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, decoder, 0)
@ -394,6 +556,20 @@ func ___decodeAsMap(data []byte, i interface{}) (bool, error) {
return true, fmt.Errorf("read length is different [%d] [%d] ", offset, decoder.Len()) return true, fmt.Errorf("read length is different [%d] [%d] ", offset, decoder.Len())
} }
return true, err return true, err
case *FetchCRLResponse:
decoder := dec.NewDecoder(data)
offset, err := ___decodeMapFetchCRLResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, decoder, 0)
if err == nil && offset != decoder.Len() {
return true, fmt.Errorf("read length is different [%d] [%d] ", offset, decoder.Len())
}
return true, err
case **FetchCRLResponse:
decoder := dec.NewDecoder(data)
offset, err := ___decodeMapFetchCRLResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(*v, decoder, 0)
if err == nil && offset != decoder.Len() {
return true, fmt.Errorf("read length is different [%d] [%d] ", offset, decoder.Len())
}
return true, err
case *ErrorResponse: case *ErrorResponse:
decoder := dec.NewDecoder(data) decoder := dec.NewDecoder(data)
offset, err := ___decodeMapErrorResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, decoder, 0) offset, err := ___decodeMapErrorResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, decoder, 0)
@ -412,6 +588,192 @@ func ___decodeAsMap(data []byte, i interface{}) (bool, error) {
return false, nil return false, nil
} }
// calculate size from git.cacert.org/cacert-gosigner/pkg/messages.FetchCRLCommand
func ___calcArraySizeFetchCRLCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v FetchCRLCommand, encoder *enc.Encoder) (int, error) {
size := 0
size += encoder.CalcStructHeaderFix(2)
size += encoder.CalcString(v.IssuerID)
if v.LastKnownID != nil {
s, err := encoder.CalcSliceLength(len(v.LastKnownID), true)
if err != nil {
return 0, err
}
size += s
for _, vv := range v.LastKnownID {
size += encoder.CalcByte(vv)
}
} else {
size += encoder.CalcNil()
}
return size, nil
}
// calculate size from git.cacert.org/cacert-gosigner/pkg/messages.FetchCRLCommand
func ___calcMapSizeFetchCRLCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v FetchCRLCommand, encoder *enc.Encoder) (int, error) {
size := 0
size += encoder.CalcStructHeaderFix(2)
size += encoder.CalcStringFix(9)
size += encoder.CalcString(v.IssuerID)
size += encoder.CalcStringFix(13)
if v.LastKnownID != nil {
s, err := encoder.CalcSliceLength(len(v.LastKnownID), true)
if err != nil {
return 0, err
}
size += s
for _, vv := range v.LastKnownID {
size += encoder.CalcByte(vv)
}
} else {
size += encoder.CalcNil()
}
return size, nil
}
// encode from git.cacert.org/cacert-gosigner/pkg/messages.FetchCRLCommand
func ___encodeArrayFetchCRLCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v FetchCRLCommand, encoder *enc.Encoder, offset int) ([]byte, int, error) {
var err error
offset = encoder.WriteStructHeaderFixAsArray(2, offset)
offset = encoder.WriteString(v.IssuerID, offset)
if v.LastKnownID != nil {
offset = encoder.WriteSliceLength(len(v.LastKnownID), offset, true)
for _, vv := range v.LastKnownID {
offset = encoder.WriteByte(vv, offset)
}
} else {
offset = encoder.WriteNil(offset)
}
return encoder.EncodedBytes(), offset, err
}
// encode from git.cacert.org/cacert-gosigner/pkg/messages.FetchCRLCommand
func ___encodeMapFetchCRLCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v FetchCRLCommand, encoder *enc.Encoder, offset int) ([]byte, int, error) {
var err error
offset = encoder.WriteStructHeaderFixAsMap(2, offset)
offset = encoder.WriteStringFix("issuer_id", 9, offset)
offset = encoder.WriteString(v.IssuerID, offset)
offset = encoder.WriteStringFix("last_known_id", 13, offset)
if v.LastKnownID != nil {
offset = encoder.WriteSliceLength(len(v.LastKnownID), offset, true)
for _, vv := range v.LastKnownID {
offset = encoder.WriteByte(vv, offset)
}
} else {
offset = encoder.WriteNil(offset)
}
return encoder.EncodedBytes(), offset, err
}
// decode to git.cacert.org/cacert-gosigner/pkg/messages.FetchCRLCommand
func ___decodeArrayFetchCRLCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v *FetchCRLCommand, decoder *dec.Decoder, offset int) (int, error) {
offset, err := decoder.CheckStructHeader(2, offset)
if err != nil {
return 0, err
}
{
var vv string
vv, offset, err = decoder.AsString(offset)
if err != nil {
return 0, err
}
v.IssuerID = vv
}
if !decoder.IsCodeNil(offset) {
var vv []byte
var vvl int
vvl, offset, err = decoder.SliceLength(offset)
if err != nil {
return 0, err
}
vv = make([]byte, vvl)
for vvi := range vv {
var vvv byte
vvv, offset, err = decoder.AsByte(offset)
if err != nil {
return 0, err
}
vv[vvi] = vvv
}
v.LastKnownID = vv
} else {
offset++
}
return offset, err
}
// decode to git.cacert.org/cacert-gosigner/pkg/messages.FetchCRLCommand
func ___decodeMapFetchCRLCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v *FetchCRLCommand, decoder *dec.Decoder, offset int) (int, error) {
keys := [][]byte{
{uint8(0x69), uint8(0x73), uint8(0x73), uint8(0x75), uint8(0x65), uint8(0x72), uint8(0x5f), uint8(0x69), uint8(0x64)}, // issuer_id
{uint8(0x6c), uint8(0x61), uint8(0x73), uint8(0x74), uint8(0x5f), uint8(0x6b), uint8(0x6e), uint8(0x6f), uint8(0x77), uint8(0x6e), uint8(0x5f), uint8(0x69), uint8(0x64)}, // last_known_id
}
offset, err := decoder.CheckStructHeader(2, offset)
if err != nil {
return 0, err
}
count := 0
for count < 2 {
var dataKey []byte
dataKey, offset, err = decoder.AsStringBytes(offset)
if err != nil {
return 0, err
}
fieldIndex := -1
for i, key := range keys {
if len(dataKey) != len(key) {
continue
}
fieldIndex = i
for dataKeyIndex := range dataKey {
if dataKey[dataKeyIndex] != key[dataKeyIndex] {
fieldIndex = -1
break
}
}
if fieldIndex >= 0 {
break
}
}
switch fieldIndex {
case 0:
{
var vv string
vv, offset, err = decoder.AsString(offset)
if err != nil {
return 0, err
}
v.IssuerID = vv
}
count++
case 1:
if !decoder.IsCodeNil(offset) {
var vv []byte
var vvl int
vvl, offset, err = decoder.SliceLength(offset)
if err != nil {
return 0, err
}
vv = make([]byte, vvl)
for vvi := range vv {
var vvv byte
vvv, offset, err = decoder.AsByte(offset)
if err != nil {
return 0, err
}
vv[vvi] = vvv
}
v.LastKnownID = vv
} else {
offset++
}
count++
default:
return 0, fmt.Errorf("unknown key[%s] found", string(dataKey))
}
}
return offset, err
}
// calculate size from git.cacert.org/cacert-gosigner/pkg/messages.HealthCommand // calculate size from git.cacert.org/cacert-gosigner/pkg/messages.HealthCommand
func ___calcArraySizeHealthCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v HealthCommand, encoder *enc.Encoder) (int, error) { func ___calcArraySizeHealthCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v HealthCommand, encoder *enc.Encoder) (int, error) {
size := 0 size := 0
@ -969,6 +1331,327 @@ func ___decodeMapHealthResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f
return offset, err return offset, err
} }
// calculate size from git.cacert.org/cacert-gosigner/pkg/messages.FetchCRLResponse
func ___calcArraySizeFetchCRLResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v FetchCRLResponse, encoder *enc.Encoder) (int, error) {
size := 0
size += encoder.CalcStructHeaderFix(5)
size += encoder.CalcString(v.IssuerID)
size += encoder.CalcBool(v.IsDelta)
size += encoder.CalcBool(v.UnChanged)
if v.CRLData != nil {
s, err := encoder.CalcSliceLength(len(v.CRLData), true)
if err != nil {
return 0, err
}
size += s
for _, vv := range v.CRLData {
size += encoder.CalcByte(vv)
}
} else {
size += encoder.CalcNil()
}
if v.CRLNumber != nil {
s, err := encoder.CalcSliceLength(len(v.CRLNumber), true)
if err != nil {
return 0, err
}
size += s
for _, vv := range v.CRLNumber {
size += encoder.CalcByte(vv)
}
} else {
size += encoder.CalcNil()
}
return size, nil
}
// calculate size from git.cacert.org/cacert-gosigner/pkg/messages.FetchCRLResponse
func ___calcMapSizeFetchCRLResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v FetchCRLResponse, encoder *enc.Encoder) (int, error) {
size := 0
size += encoder.CalcStructHeaderFix(5)
size += encoder.CalcStringFix(9)
size += encoder.CalcString(v.IssuerID)
size += encoder.CalcStringFix(8)
size += encoder.CalcBool(v.IsDelta)
size += encoder.CalcStringFix(9)
size += encoder.CalcBool(v.UnChanged)
size += encoder.CalcStringFix(8)
if v.CRLData != nil {
s, err := encoder.CalcSliceLength(len(v.CRLData), true)
if err != nil {
return 0, err
}
size += s
for _, vv := range v.CRLData {
size += encoder.CalcByte(vv)
}
} else {
size += encoder.CalcNil()
}
size += encoder.CalcStringFix(10)
if v.CRLNumber != nil {
s, err := encoder.CalcSliceLength(len(v.CRLNumber), true)
if err != nil {
return 0, err
}
size += s
for _, vv := range v.CRLNumber {
size += encoder.CalcByte(vv)
}
} else {
size += encoder.CalcNil()
}
return size, nil
}
// encode from git.cacert.org/cacert-gosigner/pkg/messages.FetchCRLResponse
func ___encodeArrayFetchCRLResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v FetchCRLResponse, encoder *enc.Encoder, offset int) ([]byte, int, error) {
var err error
offset = encoder.WriteStructHeaderFixAsArray(5, offset)
offset = encoder.WriteString(v.IssuerID, offset)
offset = encoder.WriteBool(v.IsDelta, offset)
offset = encoder.WriteBool(v.UnChanged, offset)
if v.CRLData != nil {
offset = encoder.WriteSliceLength(len(v.CRLData), offset, true)
for _, vv := range v.CRLData {
offset = encoder.WriteByte(vv, offset)
}
} else {
offset = encoder.WriteNil(offset)
}
if v.CRLNumber != nil {
offset = encoder.WriteSliceLength(len(v.CRLNumber), offset, true)
for _, vv := range v.CRLNumber {
offset = encoder.WriteByte(vv, offset)
}
} else {
offset = encoder.WriteNil(offset)
}
return encoder.EncodedBytes(), offset, err
}
// encode from git.cacert.org/cacert-gosigner/pkg/messages.FetchCRLResponse
func ___encodeMapFetchCRLResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v FetchCRLResponse, encoder *enc.Encoder, offset int) ([]byte, int, error) {
var err error
offset = encoder.WriteStructHeaderFixAsMap(5, offset)
offset = encoder.WriteStringFix("issuer_id", 9, offset)
offset = encoder.WriteString(v.IssuerID, offset)
offset = encoder.WriteStringFix("is_delta", 8, offset)
offset = encoder.WriteBool(v.IsDelta, offset)
offset = encoder.WriteStringFix("unchanged", 9, offset)
offset = encoder.WriteBool(v.UnChanged, offset)
offset = encoder.WriteStringFix("crl_data", 8, offset)
if v.CRLData != nil {
offset = encoder.WriteSliceLength(len(v.CRLData), offset, true)
for _, vv := range v.CRLData {
offset = encoder.WriteByte(vv, offset)
}
} else {
offset = encoder.WriteNil(offset)
}
offset = encoder.WriteStringFix("crl_number", 10, offset)
if v.CRLNumber != nil {
offset = encoder.WriteSliceLength(len(v.CRLNumber), offset, true)
for _, vv := range v.CRLNumber {
offset = encoder.WriteByte(vv, offset)
}
} else {
offset = encoder.WriteNil(offset)
}
return encoder.EncodedBytes(), offset, err
}
// decode to git.cacert.org/cacert-gosigner/pkg/messages.FetchCRLResponse
func ___decodeArrayFetchCRLResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v *FetchCRLResponse, decoder *dec.Decoder, offset int) (int, error) {
offset, err := decoder.CheckStructHeader(5, offset)
if err != nil {
return 0, err
}
{
var vv string
vv, offset, err = decoder.AsString(offset)
if err != nil {
return 0, err
}
v.IssuerID = vv
}
{
var vv bool
vv, offset, err = decoder.AsBool(offset)
if err != nil {
return 0, err
}
v.IsDelta = vv
}
{
var vv bool
vv, offset, err = decoder.AsBool(offset)
if err != nil {
return 0, err
}
v.UnChanged = vv
}
if !decoder.IsCodeNil(offset) {
var vv []byte
var vvl int
vvl, offset, err = decoder.SliceLength(offset)
if err != nil {
return 0, err
}
vv = make([]byte, vvl)
for vvi := range vv {
var vvv byte
vvv, offset, err = decoder.AsByte(offset)
if err != nil {
return 0, err
}
vv[vvi] = vvv
}
v.CRLData = vv
} else {
offset++
}
if !decoder.IsCodeNil(offset) {
var vv []byte
var vvl int
vvl, offset, err = decoder.SliceLength(offset)
if err != nil {
return 0, err
}
vv = make([]byte, vvl)
for vvi := range vv {
var vvv byte
vvv, offset, err = decoder.AsByte(offset)
if err != nil {
return 0, err
}
vv[vvi] = vvv
}
v.CRLNumber = vv
} else {
offset++
}
return offset, err
}
// decode to git.cacert.org/cacert-gosigner/pkg/messages.FetchCRLResponse
func ___decodeMapFetchCRLResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v *FetchCRLResponse, decoder *dec.Decoder, offset int) (int, error) {
keys := [][]byte{
{uint8(0x69), uint8(0x73), uint8(0x73), uint8(0x75), uint8(0x65), uint8(0x72), uint8(0x5f), uint8(0x69), uint8(0x64)}, // issuer_id
{uint8(0x69), uint8(0x73), uint8(0x5f), uint8(0x64), uint8(0x65), uint8(0x6c), uint8(0x74), uint8(0x61)}, // is_delta
{uint8(0x75), uint8(0x6e), uint8(0x63), uint8(0x68), uint8(0x61), uint8(0x6e), uint8(0x67), uint8(0x65), uint8(0x64)}, // unchanged
{uint8(0x63), uint8(0x72), uint8(0x6c), uint8(0x5f), uint8(0x64), uint8(0x61), uint8(0x74), uint8(0x61)}, // crl_data
{uint8(0x63), uint8(0x72), uint8(0x6c), uint8(0x5f), uint8(0x6e), uint8(0x75), uint8(0x6d), uint8(0x62), uint8(0x65), uint8(0x72)}, // crl_number
}
offset, err := decoder.CheckStructHeader(5, offset)
if err != nil {
return 0, err
}
count := 0
for count < 5 {
var dataKey []byte
dataKey, offset, err = decoder.AsStringBytes(offset)
if err != nil {
return 0, err
}
fieldIndex := -1
for i, key := range keys {
if len(dataKey) != len(key) {
continue
}
fieldIndex = i
for dataKeyIndex := range dataKey {
if dataKey[dataKeyIndex] != key[dataKeyIndex] {
fieldIndex = -1
break
}
}
if fieldIndex >= 0 {
break
}
}
switch fieldIndex {
case 0:
{
var vv string
vv, offset, err = decoder.AsString(offset)
if err != nil {
return 0, err
}
v.IssuerID = vv
}
count++
case 1:
{
var vv bool
vv, offset, err = decoder.AsBool(offset)
if err != nil {
return 0, err
}
v.IsDelta = vv
}
count++
case 2:
{
var vv bool
vv, offset, err = decoder.AsBool(offset)
if err != nil {
return 0, err
}
v.UnChanged = vv
}
count++
case 3:
if !decoder.IsCodeNil(offset) {
var vv []byte
var vvl int
vvl, offset, err = decoder.SliceLength(offset)
if err != nil {
return 0, err
}
vv = make([]byte, vvl)
for vvi := range vv {
var vvv byte
vvv, offset, err = decoder.AsByte(offset)
if err != nil {
return 0, err
}
vv[vvi] = vvv
}
v.CRLData = vv
} else {
offset++
}
count++
case 4:
if !decoder.IsCodeNil(offset) {
var vv []byte
var vvl int
vvl, offset, err = decoder.SliceLength(offset)
if err != nil {
return 0, err
}
vv = make([]byte, vvl)
for vvi := range vv {
var vvv byte
vvv, offset, err = decoder.AsByte(offset)
if err != nil {
return 0, err
}
vv[vvi] = vvv
}
v.CRLNumber = vv
} else {
offset++
}
count++
default:
return 0, fmt.Errorf("unknown key[%s] found", string(dataKey))
}
}
return offset, err
}
// calculate size from git.cacert.org/cacert-gosigner/pkg/messages.ErrorResponse // calculate size from git.cacert.org/cacert-gosigner/pkg/messages.ErrorResponse
func ___calcArraySizeErrorResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v ErrorResponse, encoder *enc.Encoder) (int, error) { func ___calcArraySizeErrorResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v ErrorResponse, encoder *enc.Encoder) (int, error) {
size := 0 size := 0