|
@@ -5,8 +5,13 @@ import (
|
|
|
"crypto/ecdsa"
|
|
|
"crypto/elliptic"
|
|
|
"crypto/rand"
|
|
|
+ "crypto/x509"
|
|
|
+ "encoding/pem"
|
|
|
"io/ioutil"
|
|
|
"log"
|
|
|
+ "os"
|
|
|
+ "path/filepath"
|
|
|
+ "time"
|
|
|
|
|
|
"github.com/go-acme/lego/v4/certcrypto"
|
|
|
"github.com/go-acme/lego/v4/certificate"
|
|
@@ -47,7 +52,7 @@ func NewACME(email string, domains []string) *ACMEHandler {
|
|
|
|
|
|
func (a *ACMEHandler) ObtainCert() {
|
|
|
log.Println("Obtaining certificate...")
|
|
|
- // Create a user. New accounts need an email and private key to start.
|
|
|
+
|
|
|
privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
|
|
if err != nil {
|
|
|
log.Fatal(err)
|
|
@@ -66,17 +71,20 @@ func (a *ACMEHandler) ObtainCert() {
|
|
|
client, err := lego.NewClient(config)
|
|
|
if err != nil {
|
|
|
log.Println(err)
|
|
|
+ return
|
|
|
}
|
|
|
|
|
|
err = client.Challenge.SetHTTP01Provider(http01.NewProviderServer("", "5002"))
|
|
|
if err != nil {
|
|
|
log.Println(err)
|
|
|
+ return
|
|
|
}
|
|
|
|
|
|
// New users will need to register
|
|
|
reg, err := client.Registration.Register(registration.RegisterOptions{TermsOfServiceAgreed: true})
|
|
|
if err != nil {
|
|
|
log.Println(err)
|
|
|
+ return
|
|
|
}
|
|
|
adminUser.Registration = reg
|
|
|
|
|
@@ -87,16 +95,66 @@ func (a *ACMEHandler) ObtainCert() {
|
|
|
certificates, err := client.Certificate.Obtain(request)
|
|
|
if err != nil {
|
|
|
log.Println(err)
|
|
|
+ return
|
|
|
}
|
|
|
|
|
|
// Each certificate comes back with the cert bytes, the bytes of the client's
|
|
|
// private key, and a certificate URL. SAVE THESE TO DISK.
|
|
|
- err = ioutil.WriteFile("./certs/"+certificates.Domain+".crt", certificates.Certificate, 0777)
|
|
|
- err = ioutil.WriteFile("./certs/"+certificates.Domain+".key", certificates.PrivateKey, 0777)
|
|
|
+ certificateName := ""
|
|
|
+ if len(a.domains) == 1 {
|
|
|
+ certificateName = certificates.Domain
|
|
|
+ } else {
|
|
|
+ certificateName = "default"
|
|
|
+ }
|
|
|
+ err = ioutil.WriteFile("./certs/"+certificateName+".crt", certificates.Certificate, 0777)
|
|
|
+ if err != nil {
|
|
|
+ log.Println(err)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ err = ioutil.WriteFile("./certs/"+certificateName+".key", certificates.PrivateKey, 0777)
|
|
|
|
|
|
if err != nil {
|
|
|
log.Println(err)
|
|
|
+ return
|
|
|
}
|
|
|
|
|
|
// ... all done.
|
|
|
}
|
|
|
+
|
|
|
+// Return a list of domains where the certificates covers
|
|
|
+func (a *ACMEHandler) CheckCertificate() {
|
|
|
+
|
|
|
+ filenames, err := os.ReadDir("./certs/")
|
|
|
+
|
|
|
+ if err != nil {
|
|
|
+ log.Println(err)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ for _, filename := range filenames {
|
|
|
+ certFilepath := filepath.Join("./certs/", filename.Name())
|
|
|
+
|
|
|
+ certBtyes, err := os.ReadFile(certFilepath)
|
|
|
+ if err != nil {
|
|
|
+ //Unable to load this file
|
|
|
+ continue
|
|
|
+ } else {
|
|
|
+ //Cert loaded. Check its expire time
|
|
|
+ block, _ := pem.Decode(certBtyes)
|
|
|
+ if block != nil {
|
|
|
+ cert, err := x509.ParseCertificate(block.Bytes)
|
|
|
+ if err == nil {
|
|
|
+ elapsed := time.Since(cert.NotAfter)
|
|
|
+ approxMonths := -int(elapsed.Hours() / (24 * 30.44))
|
|
|
+ approxDays := -int(elapsed.Hours()/24) % 30
|
|
|
+ if elapsed > 0 {
|
|
|
+ log.Println("Certificate", certFilepath, " expired")
|
|
|
+ } else {
|
|
|
+ log.Println("Certificate", certFilepath, " will still vaild for the next ", approxMonths, "m", approxDays, "d")
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+}
|