package database import ( "fmt" "github.com/go-acme/lego/v4/certcrypto" "github.com/go-acme/lego/v4/certificate" "github.com/rs/zerolog/log" ) type CertDB interface { Close() error Put(name string, cert *certificate.Resource) error Get(name string) (*certificate.Resource, error) Delete(key string) error Items(page, pageSize int) ([]*Cert, error) // Compact deprecated // TODO: remove in next version Compact() (string, error) } type Cert struct { Name string `xorm:"pk NOT NULL 'name'"` Domain string `xorm:" NOT NULL UNIQUE 'domain'"` // TODO: check: is name always same as domain? Created int64 `xorm:"created NOT NULL DEFAULT 0 'created'"` Updated int64 `xorm:"updated NOT NULL DEFAULT 0 'updated'"` ValidTill int64 `xorm:" NOT NULL DEFAULT 0 'valid_till'"` // certificate.Resource certURL string `xorm:"'cert_url'"` certStableURL string `xorm:"'cert_stable_url''"` privateKey []byte `xorm:"'private_key'"` certificate []byte `xorm:"'certificate'"` issuerCertificate []byte `xorm:"'issuer_certificate'"` // TODO: dedup ? csr []byte `xorm:"'csr'"` } func (c Cert) Raw() *certificate.Resource { return &certificate.Resource{ Domain: c.Domain, CertURL: c.certURL, CertStableURL: c.certStableURL, PrivateKey: c.privateKey, Certificate: c.certificate, IssuerCertificate: c.issuerCertificate, CSR: c.csr, } } func toCert(name string, c *certificate.Resource) (*Cert, error) { tlsCertificates, err := certcrypto.ParsePEMBundle(c.Certificate) if err != nil { return nil, err } if len(tlsCertificates) != 1 || tlsCertificates[0] == nil { err := fmt.Errorf("parsed cert resource has no or more than one cert") log.Error().Err(err).Str("name", name).Msgf("cert: %v", c) return nil, err } validTill := tlsCertificates[0].NotAfter.Unix() return &Cert{ Name: name, Domain: c.Domain, ValidTill: validTill, certURL: c.CertURL, certStableURL: c.CertStableURL, privateKey: c.PrivateKey, certificate: c.Certificate, issuerCertificate: c.IssuerCertificate, csr: c.CSR, }, nil }