package main import ( "crypto" "crypto/tls" "crypto/x509" "io" "os" "path" "github.com/dim13/acme" ) func NewFile(fname string, mode os.FileMode) (io.WriteCloser, error) { _ = os.Rename(fname, fname+".bak") flags := os.O_WRONLY | os.O_CREATE | os.O_TRUNC return os.OpenFile(fname, flags, mode) } func saveKey(fname string, key crypto.PrivateKey) error { if err := os.MkdirAll(path.Dir(fname), 0700); err != nil { return err } fd, err := NewFile(fname, 0600) if err != nil { return err } defer fd.Close() return acme.SaveKey(fd, key) } func saveCrt(fname string, certs [][]byte) error { if err := os.MkdirAll(path.Dir(fname), 0755); err != nil { return err } fd, err := NewFile(fname, 0644) if err != nil { return err } defer fd.Close() for _, crt := range certs { if err := acme.SaveCert(fd, crt); err != nil { return err } } return nil } func (d domain) Save(cert tls.Certificate) error { if err := saveKey(d.KeyFile, cert.PrivateKey); err != nil { return err } if err := saveCrt(d.CrtFile, cert.Certificate); err != nil { return err } return nil } func (d domain) Load() (tls.Certificate, error) { crt, err := tls.LoadX509KeyPair(d.CrtFile, d.KeyFile) if err != nil { return tls.Certificate{}, err } crt.Leaf, err = x509.ParseCertificate(crt.Certificate[0]) return crt, err } func (d desire) Save(key crypto.PrivateKey) error { if err := os.MkdirAll(path.Dir(d.KeyFile), 0700); err != nil { return err } fd, err := NewFile(d.KeyFile, 0600) if err != nil { return err } defer fd.Close() return acme.SaveKey(fd, key) } func (d desire) Load() (crypto.PrivateKey, error) { fd, err := os.Open(d.KeyFile) if err != nil { return nil, err } defer fd.Close() return acme.LoadKey(fd) }