snap/pkg/autocert/certs.go

58 lines
1.0 KiB
Go

package autocert
import (
"crypto/tls"
"sync"
"time"
)
type CertManager struct {
lock sync.RWMutex
cert *tls.Certificate
certPath string
keyPath string
}
// NewManager refreshes certificates before they expire
func NewManager(certPath, keyPath string) (*CertManager, error) {
m := &CertManager{
certPath: certPath,
keyPath: keyPath,
}
cert, err := tls.LoadX509KeyPair(certPath, keyPath)
if err != nil {
return nil, err
}
m.cert = &cert
go m.updater()
return m, nil
}
func (m *CertManager) tryRefresh() time.Duration {
newCert, err := tls.LoadX509KeyPair(m.certPath, m.keyPath)
if err != nil {
return time.Hour
}
m.lock.Lock()
defer m.lock.Unlock()
m.cert = &newCert
return time.Hour * 24
}
func (m *CertManager) updater() {
for {
sleep := m.tryRefresh()
time.Sleep(sleep)
}
}
func (m *CertManager) GetCertificateFunc() func(*tls.ClientHelloInfo) (*tls.Certificate, error) {
return func(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error) {
m.lock.RLock()
defer m.lock.RUnlock()
return m.cert, nil
}
}