mail/pkg/tls/tls.go

82 lines
1.3 KiB
Go

package tls
import (
"context"
"crypto/tls"
"time"
"github.com/pkg/errors"
"go.uber.org/zap"
)
const (
defaultCertFile = "/var/secrets/mail/tls.crt"
defaultKeyFile = "/var/secrets/mail/tls.key"
)
type CertManager struct {
cert *tls.Certificate
Log *zap.Logger
certFile string
keyFile string
}
func NewCertManager(certFile, keyFile string) (*CertManager, error) {
if certFile == "" {
certFile = defaultCertFile
}
if keyFile == "" {
keyFile = defaultKeyFile
}
cm := &CertManager{
certFile: certFile,
keyFile: keyFile,
}
return cm, nil
}
func (cm *CertManager) Get(_ *tls.ClientHelloInfo) (*tls.Certificate, error) {
if cm.cert == nil {
return nil, errors.New("no certificate")
}
return cm.cert, nil
}
func (cm *CertManager) Load() error {
cert, err := tls.LoadX509KeyPair(cm.certFile, cm.keyFile)
if err != nil {
return errors.Wrap(err, "failed to load certificate")
}
cm.cert = &cert
return nil
}
func (cm *CertManager) Ready() bool {
return cm.cert != nil
}
func (cm *CertManager) Watch(ctx context.Context, log *zap.Logger) error {
cm.Log = log
for {
select {
case <-time.After(time.Hour):
case <-ctx.Done():
return ctx.Err()
}
if err := cm.Load(); err != nil {
log.Error("failed to load new certificate", zap.Error(err))
continue
}
}
}