From 6884281d8654e67beb2474fbe5b3f0189c9bb703 Mon Sep 17 00:00:00 2001 From: adnano Date: Mon, 21 Sep 2020 18:21:42 -0400 Subject: [PATCH] Add support for client-side certificates --- client.go | 25 ++++++++++++++++++------- example/client/.gitignore | 2 ++ example/client/client.go | 21 ++++++++++++++++++++- example/server/server.go | 2 +- server.go | 4 ++-- 5 files changed, 43 insertions(+), 11 deletions(-) create mode 100644 example/client/.gitignore diff --git a/client.go b/client.go index a25b6d0..fda626e 100644 --- a/client.go +++ b/client.go @@ -16,7 +16,19 @@ var ( // Client is a Gemini client. type Client struct { - TLSConfig *tls.Config // TODO: Client certificate support + // The client's TLS configuration. + // To use a client-side certificate, provide it here. + // + // Example: + // + // config := tls.Config{} + // cert, err := tls.LoadX509KeyPair("example/server/server.crt", "example/server/server.key") + // if err != nil { + // panic(err) + // } + // config.Certificates = append(config.Certificates, cert) + // + TLSConfig tls.Config } // Request makes a request for the provided URL. The host is inferred from the URL. @@ -83,12 +95,11 @@ func (c *Client) Do(req *Request) (*Response, error) { host += ":1965" } - config := &tls.Config{ - // Allow self-signed certificates - // TODO: Trust on first use - InsecureSkipVerify: true, - } - conn, err := tls.Dial("tcp", host, config) + // Allow self signed certificates + config := c.TLSConfig + config.InsecureSkipVerify = true + + conn, err := tls.Dial("tcp", host, &config) if err != nil { return nil, err } diff --git a/example/client/.gitignore b/example/client/.gitignore new file mode 100644 index 0000000..37278c1 --- /dev/null +++ b/example/client/.gitignore @@ -0,0 +1,2 @@ +client.crt +client.key diff --git a/example/client/client.go b/example/client/client.go index 5b6fde2..0dac61b 100644 --- a/example/client/client.go +++ b/example/client/client.go @@ -4,14 +4,33 @@ package main import ( "bufio" + "crypto/tls" "fmt" - "git.sr.ht/~adnano/go-gemini" "log" "os" + + "git.sr.ht/~adnano/go-gemini" ) var client gemini.Client +func init() { + // Configure a client side certificate. + // To generate a certificate, run: + // + // openssl genrsa -out client.key 2048 + // openssl ecparam -genkey -name secp384r1 -out client.key + // openssl req -new -x509 -sha256 -key client.key -out client.crt -days 3650 + // + config := tls.Config{} + cert, err := tls.LoadX509KeyPair("example/client/client.crt", "example/client/client.key") + if err != nil { + log.Fatal(err) + } + config.Certificates = append(config.Certificates, cert) + client.TLSConfig = config +} + func makeRequest(url string) { resp, err := client.Request(url) if err != nil { diff --git a/example/server/server.go b/example/server/server.go index 3f0a3e3..dbb23a0 100644 --- a/example/server/server.go +++ b/example/server/server.go @@ -17,7 +17,7 @@ func main() { // openssl ecparam -genkey -name secp384r1 -out server.key // openssl req -new -x509 -sha256 -key server.key -out server.crt -days 3650 // - config := &tls.Config{} + config := tls.Config{} cert, err := tls.LoadX509KeyPair("example/server/server.crt", "example/server/server.key") if err != nil { log.Fatal(err) diff --git a/server.go b/server.go index e039f67..a42588b 100644 --- a/server.go +++ b/server.go @@ -62,7 +62,7 @@ func (r *Response) Write(w io.Writer) { // Server is a Gemini server. type Server struct { Addr string - TLSConfig *tls.Config + TLSConfig tls.Config Handler Handler } @@ -79,7 +79,7 @@ func (s *Server) ListenAndServe() error { } defer ln.Close() - tlsListener := tls.NewListener(ln, s.TLSConfig) + tlsListener := tls.NewListener(ln, &s.TLSConfig) return s.Serve(tlsListener) }