-
Notifications
You must be signed in to change notification settings - Fork 0
/
certificate.go
127 lines (112 loc) · 2.66 KB
/
certificate.go
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package main
import "encoding/pem"
import "github.com/mehmooda/acme_client/acme"
import "os"
import "time"
import "bytes"
import "crypto/sha256"
import "encoding/hex"
import "io"
import "os/exec"
func GetCertificate(domain string, client *acme.Client) {
certurl, ok := GLOBAL.HOST[domain]["CERTURL"]
if ok {
LogV("Downloading Existing Chain")
chain, err := client.GetCertChain(certurl)
if err != nil {
LogE(err)
return
}
LogV("Checking Certificate Validity")
// Not Checking chain[0].Certificate.NotBefore
// A lot of servers mess up their timezone information and have wrong time
// Needs at least 30 days validity
if time.Now().After(chain[0].Certificate.NotAfter.AddDate(0, 0, -30)) {
LogE("Certitfcate has less than 30 days validity")
} else {
LogV("Installing Chain")
InstallCertificates(domain, chain)
return
}
}
sslkey, ok := GLOBAL.HOST[domain]["SSLKEY"]
if !ok {
LogE("No SSLKEY given for", domain)
return
}
key := Import_Rsa_Key_PEM(sslkey)
if key == nil {
LogE("Unable to load SSLKEY")
return
}
_, ok = GLOBAL.HOST[domain]["SSLCERT"]
if !ok {
LogE("No SSLCERT given for", domain)
return
}
LogV("Creating New Cert")
cert, err := client.GetNewCert(key, domain)
if err != nil {
LogE(err)
}
GLOBAL.HOST[domain]["CERTURL"] = cert.Location
UpdateConfig()
LogV("Downloading New Cert Chain")
chain, err := client.GetCertChain(cert.Location)
if err != nil {
LogE(err)
return
}
LogV("Installing Chain")
InstallCertificates(domain, chain)
}
func InstallCertificates(domain string, certs []*acme.Resource) {
buf := new(bytes.Buffer)
for _, cert := range certs {
var a pem.Block
a.Type = "CERTIFICATE"
a.Bytes = cert.Certificate.Raw
err := pem.Encode(buf, &a)
if err != nil {
LogE(err)
return
}
}
CertificateFile := buf.Bytes()
var oldSHA, newSHA []byte
hasher := sha256.New()
hasher.Write(CertificateFile)
newSHA = hasher.Sum(nil)
LogV("SHA256 of Certificate File", hex.EncodeToString(newSHA))
file, err := os.Open(GLOBAL.HOST[domain]["SSLCERT"])
if err == nil {
hasher := sha256.New()
io.Copy(hasher, file)
oldSHA = hasher.Sum(nil)
LogV("SHA256 of Existing Certificate File", hex.EncodeToString(oldSHA))
file.Close()
if bytes.Equal(oldSHA, newSHA) {
LogV("Certificate already installed Not Installing")
return
}
}
file, err = os.Create(GLOBAL.HOST[domain]["SSLCERT"])
if err != nil {
LogE(err)
return
}
_, err = file.Write(CertificateFile)
if err != nil {
LogE(err)
}
file.Close()
LogV("Reloading Server")
reloadNginx()
}
func reloadNginx() {
v := exec.Command("/usr/bin/sh", "-c", "sudo systemctl reload nginx")
err := v.Run()
if err != nil {
LogE(err)
}
}