79 lines
2.3 KiB
Go
79 lines
2.3 KiB
Go
package database
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/go-acme/lego/v4/certcrypto"
|
|
"github.com/go-acme/lego/v4/certificate"
|
|
"github.com/rs/zerolog/log"
|
|
)
|
|
|
|
//go:generate go install github.com/vektra/mockery/v2@latest
|
|
//go:generate mockery --name CertDB --output . --filename mock.go --inpackage --case underscore
|
|
|
|
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)
|
|
}
|
|
|
|
type Cert struct {
|
|
Domain string `xorm:"pk NOT NULL UNIQUE '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'"`
|
|
}
|
|
|
|
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,
|
|
}
|
|
}
|
|
|
|
func toCert(name string, c *certificate.Resource) (*Cert, error) {
|
|
tlsCertificates, err := certcrypto.ParsePEMBundle(c.Certificate)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if len(tlsCertificates) == 0 || tlsCertificates[0] == nil {
|
|
err := fmt.Errorf("parsed cert resource has no cert")
|
|
log.Error().Err(err).Str("domain", c.Domain).Msgf("cert: %v", c)
|
|
return nil, err
|
|
}
|
|
validTill := tlsCertificates[0].NotAfter.Unix()
|
|
|
|
// handle wildcard certs
|
|
if name[:1] == "." {
|
|
name = "*" + name
|
|
}
|
|
if name != c.Domain {
|
|
err := fmt.Errorf("domain key '%s' and cert domain '%s' not equal", name, c.Domain)
|
|
log.Error().Err(err).Msg("toCert conversion did discover mismatch")
|
|
// TODO: fail hard: return nil, err
|
|
}
|
|
|
|
return &Cert{
|
|
Domain: c.Domain,
|
|
ValidTill: validTill,
|
|
|
|
CertURL: c.CertURL,
|
|
CertStableURL: c.CertStableURL,
|
|
PrivateKey: c.PrivateKey,
|
|
Certificate: c.Certificate,
|
|
IssuerCertificate: c.IssuerCertificate,
|
|
}, nil
|
|
}
|