-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcert.go
More file actions
91 lines (74 loc) · 1.87 KB
/
cert.go
File metadata and controls
91 lines (74 loc) · 1.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package main
import (
"crypto/tls"
"fmt"
"goFactServView/cwlog"
"os"
"sync"
"time"
)
var (
certLock sync.RWMutex
currentCert *tls.Certificate
)
func autoUpdateCert() {
fullchainStat, privkeyStat := certFilesStat()
for {
time.Sleep(time.Minute)
updatedFullchain, updatedPrivkey := certFilesStat()
if updatedFullchain == nil || updatedPrivkey == nil {
continue
}
if certStatChanged(fullchainStat, updatedFullchain) || certStatChanged(privkeyStat, updatedPrivkey) {
if err := reloadCerts(); err != nil {
cwlog.DoLog(true, "Cert reload failed: %v", err)
continue
}
fullchainStat = updatedFullchain
privkeyStat = updatedPrivkey
cwlog.DoLog(true, "Reloaded TLS certificate.")
}
}
}
func reloadCerts() error {
cert, err := tls.LoadX509KeyPair("data/certs/fullchain.pem", "data/certs/privkey.pem")
if err != nil {
return fmt.Errorf("error loading TLS key pair data/certs/(fullchain.pem, privkey.pem): %w", err)
}
certLock.Lock()
currentCert = &cert
certLock.Unlock()
return nil
}
func loadCerts() error {
if err := reloadCerts(); err != nil {
return err
}
cwlog.DoLog(true, "Loaded certs.")
return nil
}
func getCertificate(*tls.ClientHelloInfo) (*tls.Certificate, error) {
certLock.RLock()
defer certLock.RUnlock()
if currentCert == nil {
return nil, fmt.Errorf("TLS certificate is not loaded")
}
return currentCert, nil
}
func certFilesStat() (*os.FileInfo, *os.FileInfo) {
fullchainStat, err := os.Stat("data/certs/fullchain.pem")
if err != nil {
return nil, nil
}
privkeyStat, err := os.Stat("data/certs/privkey.pem")
if err != nil {
return nil, nil
}
return &fullchainStat, &privkeyStat
}
func certStatChanged(previous, current *os.FileInfo) bool {
if previous == nil || current == nil {
return previous != current
}
return (*previous).Size() != (*current).Size() || (*previous).ModTime() != (*current).ModTime()
}