flounder

A simple gemini site builder
Log | Files | Refs | README | LICENSE

commit 68ebfc7e91bc37a6af19fa20729280624a9fb50d
parent 60827dbbdafd978ba7aab4dfeaf136b77a8bba43
Author: alex wennerberg <alex@alexwennerberg.com>
Date:   Fri, 30 Oct 2020 23:19:32 -0700

Use new go-gemini cert flow

Diffstat:
Acert.go | 46++++++++++++++++++++++++++++++++++++++++++++++
Mconfig.go | 1+
Mexample-config.toml | 5++++-
Mgemini.go | 21+++++++++++----------
Mgo.mod | 2+-
Mgo.sum | 4++--
6 files changed, 65 insertions(+), 14 deletions(-)

diff --git a/cert.go b/cert.go @@ -0,0 +1,46 @@ +package main + +import ( + "crypto" + "crypto/tls" + "crypto/x509" + "encoding/pem" + "io" + "os" +) + +// writeCertificate writes the provided certificate and private key +// to path.crt and path.key respectively. +func writeCertificate(path string, cert tls.Certificate) error { + // Write the certificate + crtPath := path + ".crt" + crtOut, err := os.OpenFile(crtPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) + if err != nil { + return err + } + if err := marshalX509Certificate(crtOut, cert.Leaf.Raw); err != nil { + return err + } + + // Write the private key + keyPath := path + ".key" + keyOut, err := os.OpenFile(keyPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) + if err != nil { + return err + } + return marshalPrivateKey(keyOut, cert.PrivateKey) +} + +// marshalX509Certificate writes a PEM-encoded version of the given certificate. +func marshalX509Certificate(w io.Writer, cert []byte) error { + return pem.Encode(w, &pem.Block{Type: "CERTIFICATE", Bytes: cert}) +} + +// marshalPrivateKey writes a PEM-encoded version of the given private key. +func marshalPrivateKey(w io.Writer, priv crypto.PrivateKey) error { + privBytes, err := x509.MarshalPKCS8PrivateKey(priv) + if err != nil { + return err + } + return pem.Encode(w, &pem.Block{Type: "PRIVATE KEY", Bytes: privBytes}) +} diff --git a/config.go b/config.go @@ -15,6 +15,7 @@ type Config struct { SecretKey string DBFile string LogFile string + GeminiCertStore string CookieStoreKey string OkExtensions []string MaxFileSize int diff --git a/example-config.toml b/example-config.toml @@ -12,7 +12,10 @@ HttpsEnabled=false FilesDirectory="./files" LogFile="./flounder.log" -# A wildcard TLS cert +# Gemini autogenerates self-signed certs +GeminiCertStore="./" + +# A wildcard TLS cert for HTTPS. TLSCertFile="./server.crt" TLSKeyFile="./server.key" diff --git a/gemini.go b/gemini.go @@ -11,6 +11,7 @@ import ( "path" "path/filepath" "text/template" + "time" ) func gmiIndex(w *gmi.ResponseWriter, r *gmi.Request) { @@ -70,17 +71,17 @@ func runGeminiServer() { hostname := strings.SplitN(c.Host, ":", 2)[0] // is this necc? - server.GetCertificate = func(hostname string, store *gmi.CertificateStore) *tls.Certificate { - cert, err := store.Lookup(hostname) - if err != nil { - cert, err := tls.LoadX509KeyPair(c.TLSCertFile, c.TLSKeyFile) - if err != nil { - log.Fatal("Invalid TLS cert") - } - store.Add(hostname, cert) - return &cert + server.CreateCertificate = func(hostname string) (tls.Certificate, error) { + log.Println("Generating certificate for", hostname) + cert, err := gmi.CreateCertificate(gmi.CertificateOptions{ + DNSNames: []string{hostname}, + Duration: time.Minute, // for testing purposes + }) + if err == nil { + // Write the new certificate to disk + err = writeCertificate(path.Join(c.GeminiCertStore, hostname), cert) } - return cert + return cert, err } var mux gmi.ServeMux diff --git a/go.mod b/go.mod @@ -3,7 +3,7 @@ module git.sr.ht/flounder go 1.15 require ( - git.sr.ht/~adnano/go-gemini v0.1.1 + git.sr.ht/~adnano/go-gemini v0.1.3 github.com/BurntSushi/toml v0.3.1 github.com/gorilla/handlers v1.5.1 github.com/gorilla/sessions v1.2.1 diff --git a/go.sum b/go.sum @@ -1,5 +1,5 @@ -git.sr.ht/~adnano/go-gemini v0.1.1 h1:g6OwUxLviy6dkPiuW2eRQP5Fow412vUsKmKYbCr2H9U= -git.sr.ht/~adnano/go-gemini v0.1.1/go.mod h1:If1VxEWcZDrRt5FeAFnGTcM2Ud1E3BXs3VJ5rnZWKq0= +git.sr.ht/~adnano/go-gemini v0.1.3 h1:uClB4mzTkHBMKBde63/EzrsIhRuHxxaNHVRf1/gApXU= +git.sr.ht/~adnano/go-gemini v0.1.3/go.mod h1:If1VxEWcZDrRt5FeAFnGTcM2Ud1E3BXs3VJ5rnZWKq0= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ=