diff options
| author | Adnan Maolood <[email protected]> | 2020-10-31 16:33:56 -0400 |
|---|---|---|
| committer | Adnan Maolood <[email protected]> | 2020-10-31 16:33:56 -0400 |
| commit | 14ef3be6fe38ea697c2f09be545d0fbb73c1d832 (patch) | |
| tree | 81e72d6d11de2a47d44941b59a29ee28449a2568 /cert.go | |
| parent | Call CreateCertificate for missing certificates (diff) | |
| download | go-gemini-14ef3be6fe38ea697c2f09be545d0fbb73c1d832.tar.xz go-gemini-14ef3be6fe38ea697c2f09be545d0fbb73c1d832.zip | |
server: Automatically write new certificates to disk
Diffstat (limited to 'cert.go')
| -rw-r--r-- | cert.go | 44 |
1 files changed, 44 insertions, 0 deletions
@@ -6,8 +6,11 @@ import ( "crypto/rand" "crypto/tls" "crypto/x509" + "encoding/pem" + "log" "math/big" "net" + "os" "path/filepath" "strings" "time" @@ -17,6 +20,8 @@ import ( // The zero value of CertificateStore is an empty store ready to use. type CertificateStore struct { store map[string]tls.Certificate + dir bool + path string } // Add adds a certificate for the given scope to the store. @@ -32,6 +37,15 @@ func (c *CertificateStore) Add(scope string, cert tls.Certificate) { cert.Leaf = parsed } } + if c.dir { + // Write certificates + log.Printf("Writing certificate for %s to disk", scope) + certPath := filepath.Join(c.path, scope+".crt") + keyPath := filepath.Join(c.path, scope+".key") + if err := WriteCertificate(cert, certPath, keyPath); err != nil { + log.Printf("Failed to write certificate to disk: %s", err) + } + } c.store[scope] = cert } @@ -53,6 +67,7 @@ func (c *CertificateStore) Lookup(scope string) (*tls.Certificate, error) { // in the form scope.crt and scope.key. // For example, the hostname "localhost" would have the corresponding files // localhost.crt (certificate) and localhost.key (private key). +// New certificates will be written to this directory. func (c *CertificateStore) Load(path string) error { matches, err := filepath.Glob(filepath.Join(path, "*.crt")) if err != nil { @@ -67,6 +82,8 @@ func (c *CertificateStore) Load(path string) error { scope := strings.TrimSuffix(filepath.Base(crtPath), ".crt") c.Add(scope, cert) } + c.dir = true + c.path = path return nil } @@ -133,3 +150,30 @@ func newX509KeyPair(options CertificateOptions) (*x509.Certificate, crypto.Priva } return cert, priv, nil } + +// WriteCertificate writes the provided certificate and private key +// to certPath and keyPath respectively. +func WriteCertificate(cert tls.Certificate, certPath, keyPath string) error { + certOut, err := os.OpenFile(certPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) + if err != nil { + return err + } + defer certOut.Close() + if err := pem.Encode(certOut, &pem.Block{ + Type: "CERTIFICATE", + Bytes: cert.Leaf.Raw, + }); err != nil { + return err + } + + keyOut, err := os.OpenFile(keyPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) + if err != nil { + return err + } + defer keyOut.Close() + privBytes, err := x509.MarshalPKCS8PrivateKey(cert.PrivateKey) + if err != nil { + return err + } + return pem.Encode(keyOut, &pem.Block{Type: "PRIVATE KEY", Bytes: privBytes}) +} |