certs.go 1.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. package autocert
  2. import (
  3. "crypto/tls"
  4. "sync"
  5. "time"
  6. )
  7. type CertManager struct {
  8. lock sync.RWMutex
  9. cert *tls.Certificate
  10. certPath string
  11. keyPath string
  12. }
  13. // NewManager refreshes certificates before they expire
  14. func NewManager(certPath, keyPath string) (*CertManager, error) {
  15. m := &CertManager{
  16. certPath: certPath,
  17. keyPath: keyPath,
  18. }
  19. cert, err := tls.LoadX509KeyPair(certPath, keyPath)
  20. if err != nil {
  21. return nil, err
  22. }
  23. m.cert = &cert
  24. go m.updater()
  25. return m, nil
  26. }
  27. func (m *CertManager) tryRefresh() time.Duration {
  28. newCert, err := tls.LoadX509KeyPair(m.certPath, m.keyPath)
  29. if err != nil {
  30. return time.Hour
  31. }
  32. m.lock.Lock()
  33. defer m.lock.Unlock()
  34. m.cert = &newCert
  35. return time.Hour * 24
  36. }
  37. func (m *CertManager) updater() {
  38. for {
  39. sleep := m.tryRefresh()
  40. time.Sleep(sleep)
  41. }
  42. }
  43. func (m *CertManager) GetCertificateFunc() func(*tls.ClientHelloInfo) (*tls.Certificate, error) {
  44. return func(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error) {
  45. m.lock.RLock()
  46. defer m.lock.RUnlock()
  47. return m.cert, nil
  48. }
  49. }