58 lines
1.0 KiB
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
|
|
}
|
|
}
|