diff --git a/cmd/signer/main.go b/cmd/signer/main.go index 2f3e239..44214cc 100644 --- a/cmd/signer/main.go +++ b/cmd/signer/main.go @@ -85,7 +85,7 @@ func main() { healthHandler := health.New(version, access) - revokingRepositories, err := configureRepositories(caConfig) + revokingRepositories, err := configureRepositories(caConfig, logger) if err != nil { logger.WithError(err).Fatal("could not setup revoking repositories") } @@ -117,20 +117,21 @@ func main() { func configureRepositories( caConfig *config.SignerConfig, + logger *logrus.Logger, ) (map[string]*revoking.X509Revoking, error) { var err error result := make(map[string]*revoking.X509Revoking) 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 { return nil, err } } 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 { return nil, err } @@ -139,7 +140,11 @@ func configureRepositories( 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) if err != nil { 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.Certificate, caDef.KeyPair, + logger, ), nil } diff --git a/go.mod b/go.mod index 95661e2..bbce149 100644 --- a/go.mod +++ b/go.mod @@ -16,6 +16,8 @@ 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/miekg/pkcs11 v1.1.1 // indirect github.com/pkg/errors v0.9.1 // indirect diff --git a/go.sum b/go.sum index dc95337..c803152 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,9 @@ 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/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/go.mod h1:7jEdnm+qBcxl8PC0zyp7vxcpSRnzXSt9r39tpTVGlwA= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= diff --git a/internal/handler/msgpack.go b/internal/handler/msgpack.go index c2b196c..cca5c0d 100644 --- a/internal/handler/msgpack.go +++ b/internal/handler/msgpack.go @@ -20,6 +20,7 @@ package handler import ( "errors" "fmt" + "math/big" "sync" "time" @@ -242,16 +243,31 @@ func (m *MsgPackHandler) handleHealthCommand() (*messages.HealthResponse, 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 { return nil, fmt.Errorf("could not fetch CRL: %w", err) } - return &messages.FetchCRLResponse{ - IsDelta: false, - CRLNumber: res.Number, - CRLData: res.CRLData, - }, nil + unchanged := crlNumber != nil && crlNumber.Cmp(res.Number) == 0 + + response := &messages.FetchCRLResponse{ + IssuerID: command.IssuerID, + 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) { diff --git a/internal/x509/openssl/repository.go b/internal/x509/openssl/repository.go index 8010f5e..5ff8aab 100644 --- a/internal/x509/openssl/repository.go +++ b/internal/x509/openssl/repository.go @@ -27,6 +27,7 @@ import ( "math/big" "os" "path" + "path/filepath" "strings" "sync" "time" @@ -96,6 +97,70 @@ type Repository struct { crlNumberFileName string lock sync.Locker 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) { @@ -420,15 +485,21 @@ func NewFileRepository(baseDirectory string) (*Repository, error) { 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 { 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{ indexFileName: path.Join(baseDirectory, "index.txt"), crlNumberFileName: path.Join(baseDirectory, "crlnumber"), + crlDirectory: path.Join(baseDirectory, "crls"), lock: &sync.Mutex{}, }, nil } diff --git a/internal/x509/revoking/repository.go b/internal/x509/revoking/repository.go index a5b3705..cf2006d 100644 --- a/internal/x509/revoking/repository.go +++ b/internal/x509/revoking/repository.go @@ -26,6 +26,9 @@ import ( type Repository interface { // StoreRevocation stores information about a revoked certificate. StoreRevocation(*pkix.RevokedCertificate) error + LoadCRL(*big.Int) ([]byte, error) + StoreCRL(*big.Int, []byte) error RevokedCertificates() ([]pkix.RevokedCertificate, error) NextCRLNumber() (*big.Int, error) + CleanUp() } diff --git a/internal/x509/revoking/revoking.go b/internal/x509/revoking/revoking.go index 158ab67..8c28b0e 100644 --- a/internal/x509/revoking/revoking.go +++ b/internal/x509/revoking/revoking.go @@ -28,6 +28,9 @@ import ( "math/big" "strings" "time" + + "github.com/balacode/go-delta" + "github.com/sirupsen/logrus" ) var OidCRLReason = asn1.ObjectIdentifier{2, 5, 29, 21} @@ -93,6 +96,7 @@ type X509Revoking struct { crlAlgorithm x509.SignatureAlgorithm crlIssuer *x509.Certificate signer crypto.Signer + logger *logrus.Logger } type RevokeCertificate struct { @@ -108,8 +112,9 @@ func NewRevokeCertificate(serialNumber *big.Int, reason CRLReason) *RevokeCertif } type CRLInformation struct { - CRL []byte // DER encoded CRL - Number *big.Int + CRL []byte // DER encoded CRL + Number *big.Int + NextUpdate time.Time } func (r *X509Revoking) Revoke(revokeCertificate *RevokeCertificate) (*pkix.RevokedCertificate, error) { @@ -126,7 +131,7 @@ func (r *X509Revoking) Revoke(revokeCertificate *RevokeCertificate) (*pkix.Revok return revoked, nil } -func (r *X509Revoking) CreateCRL() (*CRLInformation, error) { +func (r *X509Revoking) createCRL() (*CRLInformation, error) { revoked, err := r.repository.RevokedCertificates() if err != nil { 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) } + nextUpdate := time.Now().UTC().Add(defaultCRLValidity) + list, err := x509.CreateRevocationList(rand.Reader, &x509.RevocationList{ SignatureAlgorithm: r.crlAlgorithm, RevokedCertificates: revoked, Number: nextNumber, - NextUpdate: time.Now().UTC().Add(defaultCRLValidity), + ThisUpdate: time.Now().UTC(), + NextUpdate: nextUpdate, }, r.crlIssuer, r.signer) if err != nil { 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( @@ -155,12 +206,20 @@ func NewX509Revoking( crlAlgorithm x509.SignatureAlgorithm, issuer *x509.Certificate, signer crypto.Signer, + logger *logrus.Logger, ) *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 { CRLData []byte + IsDelta bool Number *big.Int } @@ -172,16 +231,45 @@ func NewFetchCRLHandler(repositories map[string]*X509Revoking) *FetchCRLHandler 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] if !ok { return nil, fmt.Errorf("unknown issuer ID %s", issuerID) } - currentCRL, err := repo.CreateCRL() + if repo.signer == nil { + return nil, fmt.Errorf("key for issuer ID %s is not available", issuerID) + } + + 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 nil, fmt.Errorf("could not create CRL for issuer ID %s: %w", issuerID, err) + 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: currentCRL.CRL, Number: currentCRL.Number}, nil + return &Result{CRLData: patchBytes, Number: currentCRL.Number, IsDelta: true}, nil } diff --git a/internal/x509/revoking/revoking_test.go b/internal/x509/revoking/revoking_test.go index 9a0d1af..76d59e9 100644 --- a/internal/x509/revoking/revoking_test.go +++ b/internal/x509/revoking/revoking_test.go @@ -18,6 +18,7 @@ limitations under the License. package revoking_test import ( + "bytes" "crypto/rand" "crypto/rsa" "crypto/x509" @@ -28,6 +29,7 @@ import ( "math/big" "testing" + "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -49,9 +51,36 @@ func randomSerial(t *testing.T) *big.Int { type testRepo struct { crlNumber *big.Int + crls map[string][]byte + current string 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) { newNumber := new(big.Int).Add(t.crlNumber, big.NewInt(1)) @@ -74,7 +103,9 @@ func (t *testRepo) StoreRevocation(revoked *pkix.RevokedCertificate) error { return nil } -type brokenRepo struct{} +type brokenRepo struct { + noStoreRepo +} func (r *brokenRepo) NextCRLNumber() (*big.Int, error) { return nil, errors.New("don't know") @@ -88,14 +119,28 @@ func (*brokenRepo) StoreRevocation(_ *pkix.RevokedCertificate) error { return errors.New("cannot store") } +type noStoreRepo struct{} + +func (r noStoreRepo) StoreRevocation(_ *pkix.RevokedCertificate) error { + // do nothing + return nil +} + type brokenRepoNoCrlNumber struct { + noStoreRepo +} + +func (r noStoreRepo) LoadCRL(_ *big.Int) ([]byte, error) { + return nil, errors.New("no CRL") } -func (b brokenRepoNoCrlNumber) StoreRevocation(_ *pkix.RevokedCertificate) error { +func (r noStoreRepo) StoreCRL(_ *big.Int, _ []byte) error { // do nothing return nil } +func (r noStoreRepo) CleanUp() {} + func (b brokenRepoNoCrlNumber) RevokedCertificates() ([]pkix.RevokedCertificate, error) { return make([]pkix.RevokedCertificate, 0), nil } @@ -105,11 +150,7 @@ func (b brokenRepoNoCrlNumber) NextCRLNumber() (*big.Int, error) { } type brokenRepoNoRevocations struct { -} - -func (b brokenRepoNoRevocations) StoreRevocation(_ *pkix.RevokedCertificate) error { - // do nothing - return nil + noStoreRepo } func (b brokenRepoNoRevocations) RevokedCertificates() ([]pkix.RevokedCertificate, error) { @@ -121,11 +162,18 @@ func (b brokenRepoNoRevocations) NextCRLNumber() (*big.Int, error) { } 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) - 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) @@ -149,7 +197,10 @@ func TestX509Revoking_Revoke(t *testing.T) { func TestX509Revoking_Revoke_BrokenRepo(t *testing.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) @@ -163,11 +214,12 @@ func TestX509Revoking_Revoke_BrokenRepo(t *testing.T) { func TestX509Revoking_CreateCRL(t *testing.T) { key, certificate := prepareTestCA(t) + logger := logrus.New() + logger.SetOutput(&bytes.Buffer{}) + r := revoking.NewX509Revoking( - &testRepo{revoked: make([]pkix.RevokedCertificate, 0), crlNumber: big.NewInt(0)}, - x509.SHA256WithRSA, - certificate, - key, + &testRepo{revoked: make([]pkix.RevokedCertificate, 0), crlNumber: big.NewInt(0), crls: map[string][]byte{}}, + x509.SHA256WithRSA, certificate, key, logger, ) serial := randomSerial(t) @@ -175,7 +227,7 @@ func TestX509Revoking_CreateCRL(t *testing.T) { _, err := r.Revoke(revoking.NewRevokeCertificate(serial, revoking.CRLReasonKeyCompromise)) require.NoError(t, err) - crl, err := r.CreateCRL() + crl, err := r.GetCRL(nil) assert.NoError(t, err) assert.NotNil(t, crl) @@ -200,48 +252,55 @@ func TestX509Revoking_CreateCRL(t *testing.T) { assert.True(t, found) } -func TestX509Revoking_CreateCRL_BrokenRepoNoRevocations(t *testing.T) { +func TestX509Revoking_GetCRL_BrokenRepoNoRevocations(t *testing.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) _, err := r.Revoke(revoking.NewRevokeCertificate(serial, revoking.CRLReasonKeyCompromise)) require.NoError(t, err) - crl, err := r.CreateCRL() + crl, err := r.GetCRL(nil) assert.Error(t, err) assert.ErrorContains(t, err, "could not get revocation information") assert.Nil(t, crl) } -func TestX509Revoking_CreateCRL_BrokenRepoNoCRLNumber(t *testing.T) { +func TestX509Revoking_GetCRL_BrokenRepoNoCRLNumber(t *testing.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) _, err := r.Revoke(revoking.NewRevokeCertificate(serial, revoking.CRLReasonKeyCompromise)) require.NoError(t, err) - crl, err := r.CreateCRL() + crl, err := r.GetCRL(nil) assert.Error(t, err) assert.ErrorContains(t, err, "could not get next CRL number") assert.Nil(t, crl) } -func TestX509Revoking_CreateCRL_WrongAlgorithm(t *testing.T) { +func TestX509Revoking_GetCRL_WrongAlgorithm(t *testing.T) { key, certificate := prepareTestCA(t) + logger := logrus.New() + logger.SetOutput(&bytes.Buffer{}) + r := revoking.NewX509Revoking( - &testRepo{revoked: make([]pkix.RevokedCertificate, 0), crlNumber: big.NewInt(0)}, - x509.ECDSAWithSHA256, - certificate, - key, + &testRepo{revoked: make([]pkix.RevokedCertificate, 0), crlNumber: big.NewInt(0), crls: map[string][]byte{}}, + x509.ECDSAWithSHA256, certificate, key, logger, ) serial := randomSerial(t) @@ -249,7 +308,7 @@ func TestX509Revoking_CreateCRL_WrongAlgorithm(t *testing.T) { _, err := r.Revoke(revoking.NewRevokeCertificate(serial, revoking.CRLReasonKeyCompromise)) require.NoError(t, err) - crl, err := r.CreateCRL() + crl, err := r.GetCRL(nil) assert.Error(t, err) assert.ErrorContains(t, err, "could not sign revocation list") diff --git a/pkg/messages/messages.go b/pkg/messages/messages.go index 7b1c759..e45f7c1 100644 --- a/pkg/messages/messages.go +++ b/pkg/messages/messages.go @@ -102,8 +102,8 @@ func (r *ResponseAnnounce) String() string { } type FetchCRLCommand struct { - IssuerID string `msgpack:"issuer_id"` - LastKnownID *big.Int `msgpack:"last_known_id"` + IssuerID string `msgpack:"issuer_id"` + LastKnownID []byte `msgpack:"last_known_id"` } func (f *FetchCRLCommand) String() string { @@ -112,7 +112,7 @@ func (f *FetchCRLCommand) String() string { _, _ = fmt.Fprintf(builder, "issuerId='%s'", f.IssuerID) 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() @@ -226,38 +226,54 @@ func (h *HealthResponse) String() string { type FetchCRLResponse struct { IssuerID string `msgpack:"issuer_id"` IsDelta bool `msgpack:"is_delta"` + UnChanged bool `msgpack:"unchanged"` CRLData []byte `msgpack:"crl_data"` - CRLNumber *big.Int + CRLNumber []byte `msgpack:"crl_number"` } func (r *FetchCRLResponse) String() string { 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 { _, _ = fmt.Fprint(builder, ", delta CRL data not shown") - } else { - revocationList, err := x509.ParseRevocationList(r.CRLData) - 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, - }) - } + + return builder.String() } + 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() } diff --git a/pkg/messages/resolver.msgpackgen.go b/pkg/messages/resolver.msgpackgen.go index 7180b8b..971ce01 100644 --- a/pkg/messages/resolver.msgpackgen.go +++ b/pkg/messages/resolver.msgpackgen.go @@ -26,6 +26,36 @@ func ___encode(i interface{}) ([]byte, error) { // encodeAsArray func ___encodeAsArray(i interface{}) ([]byte, error) { 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: encoder := enc.NewEncoder() 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 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: encoder := enc.NewEncoder() size, err := ___calcArraySizeErrorResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, encoder) @@ -153,6 +213,36 @@ func ___encodeAsArray(i interface{}) ([]byte, error) { // encodeAsMap func ___encodeAsMap(i interface{}) ([]byte, error) { 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: encoder := enc.NewEncoder() 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 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: encoder := enc.NewEncoder() size, err := ___calcMapSizeErrorResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, encoder) @@ -289,6 +409,20 @@ func ___decode(data []byte, i interface{}) (bool, error) { // decodeAsArray func ___decodeAsArray(data []byte, i interface{}) (bool, error) { 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: decoder := dec.NewDecoder(data) 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, 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: decoder := dec.NewDecoder(data) offset, err := ___decodeArrayErrorResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, decoder, 0) @@ -352,6 +500,20 @@ func ___decodeAsArray(data []byte, i interface{}) (bool, error) { // decodeAsMap func ___decodeAsMap(data []byte, i interface{}) (bool, error) { 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: decoder := dec.NewDecoder(data) 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, 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: decoder := dec.NewDecoder(data) offset, err := ___decodeMapErrorResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v, decoder, 0) @@ -412,6 +588,192 @@ func ___decodeAsMap(data []byte, i interface{}) (bool, error) { 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 func ___calcArraySizeHealthCommand_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v HealthCommand, encoder *enc.Encoder) (int, error) { size := 0 @@ -969,6 +1331,327 @@ func ___decodeMapHealthResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f 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 func ___calcArraySizeErrorResponse_e587a81c7cb163b35488bdef0f58c292f99f4bd65a81377f81e5b18c3d86855d(v ErrorResponse, encoder *enc.Encoder) (int, error) { size := 0