diff options
| author | Adnan Maolood <[email protected]> | 2020-10-28 16:02:04 -0400 |
|---|---|---|
| committer | Adnan Maolood <[email protected]> | 2020-10-28 16:02:04 -0400 |
| commit | b5fbd197a15e6991552c48f401206ead0501b52d (patch) | |
| tree | 5f69fc679f8eee9a92dcd6ca11b2651024609a9f | |
| parent | Use strings.Builder in Fingerprint (diff) | |
| download | go-gemini-b5fbd197a15e6991552c48f401206ead0501b52d.tar.xz go-gemini-b5fbd197a15e6991552c48f401206ead0501b52d.zip | |
Update documentation
| -rw-r--r-- | cert.go | 29 | ||||
| -rw-r--r-- | client.go | 22 | ||||
| -rw-r--r-- | doc.go | 24 | ||||
| -rw-r--r-- | server.go | 9 |
4 files changed, 38 insertions, 46 deletions
@@ -8,7 +8,6 @@ import ( "crypto/x509" "math/big" "net" - "path" "path/filepath" "strings" "time" @@ -36,9 +35,9 @@ func (c *CertificateStore) Add(scope string, cert tls.Certificate) { c.store[scope] = cert } -// Lookup returns the certificate for the given hostname. -func (c *CertificateStore) Lookup(hostname string) (*tls.Certificate, error) { - cert, ok := c.store[hostname] +// Lookup returns the certificate for the given scope. +func (c *CertificateStore) Lookup(scope string) (*tls.Certificate, error) { + cert, ok := c.store[scope] if !ok { return nil, ErrCertificateUnknown } @@ -49,25 +48,9 @@ func (c *CertificateStore) Lookup(hostname string) (*tls.Certificate, error) { return &cert, nil } -// lookup returns the certificate for the given hostname + path. -func (c *CertificateStore) lookup(scope string) (*tls.Certificate, error) { - for { - cert, err := c.Lookup(scope) - switch err { - case ErrCertificateExpired, nil: - return cert, err - } - scope = path.Dir(scope) - if scope == "." { - break - } - } - return nil, ErrCertificateUnknown -} - // Load loads certificates from the given path. // The path should lead to a directory containing certificates and private keys -// in the form hostname.crt and hostname.key. +// 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). func (c *CertificateStore) Load(path string) error { @@ -81,8 +64,8 @@ func (c *CertificateStore) Load(path string) error { if err != nil { continue } - hostname := strings.TrimSuffix(filepath.Base(crtPath), ".crt") - c.Add(hostname, cert) + scope := strings.TrimSuffix(filepath.Base(crtPath), ".crt") + c.Add(scope, cert) } return nil } @@ -6,6 +6,7 @@ import ( "crypto/x509" "net" "net/url" + "path" "strings" ) @@ -153,12 +154,23 @@ func (c *Client) getClientCertificate(req *Request) (*tls.Certificate, error) { if req.Certificate != nil { return req.Certificate, nil } - hostname, path := req.URL.Hostname(), strings.TrimSuffix(req.URL.Path, "/") - if cert, err := c.Certificates.lookup(hostname + path); err == nil { - // Remember the certificate used - req.Certificate = cert - return cert, nil + + // Search recursively for the certificate + scope := req.URL.Hostname() + strings.TrimSuffix(req.URL.Path, "/") + for { + cert, err := c.Certificates.Lookup(scope) + if err == nil { + return cert, err + } + if err == ErrCertificateExpired { + break + } + scope = path.Dir(scope) + if scope == "." { + break + } } + return &tls.Certificate{}, nil } @@ -41,22 +41,12 @@ Clients can control when to trust certificates with TrustCertificate: return knownHosts.Lookup(hostname, cert) } -Clients can control what to do when a server requests a certificate: - - client.GetCertificate = func(hostname string, store *gemini.CertificateStore) *tls.Certificate { - // If the certificate is in the store, return it - if cert, err := store.Lookup(hostname); err == nil { - return &cert - } - // Otherwise, generate a certificate - duration := time.Hour - cert, err := gemini.NewCertificate(hostname, duration) - if err != nil { - return nil - } - // Store and return the certificate - store.Add(hostname, cert) - return &cert +Clients can create client certificates upon the request of a server: + + client.CreateCertificate = func(hostname, path string) *tls.Certificate { + return gemini.CreateCertificate(gemini.CertificateOptions{ + Duration: time.Hour, + }) } Server is a Gemini server. @@ -65,7 +55,7 @@ Server is a Gemini server. Servers must be configured with certificates: - err := server.CertificateStore.Load("/var/lib/gemini/certs") + err := server.Certificates.Load("/var/lib/gemini/certs") if err != nil { // handle error } @@ -36,9 +36,16 @@ type responderKey struct { } // Register registers a responder for the given pattern. -// Patterns must be in the form of scheme://hostname (e.g. gemini://example.com). +// +// Patterns must be in the form of hostname or scheme://hostname +// (e.g. gemini://example.com). // If no scheme is specified, a default scheme of gemini:// is assumed. +// // Wildcard patterns are supported (e.g. *.example.com). +// To register a certificate for a wildcard domain, call Certificates.Add: +// +// var s gemini.Server +// s.Certificates.Add("*.example.com", cert) func (s *Server) Register(pattern string, responder Responder) { if pattern == "" { panic("gemini: invalid pattern") |