diff options
| author | Adnan Maolood <[email protected]> | 2020-10-28 13:40:25 -0400 |
|---|---|---|
| committer | Adnan Maolood <[email protected]> | 2020-10-28 13:41:24 -0400 |
| commit | fbd97a62dec02ad22b7cf520cfc6ab519ea0e990 (patch) | |
| tree | 8a19117713cddce2d3ed2d31c24bec59fe616a48 /cert.go | |
| parent | Add ErrInputRequired and ErrCertificateRequired (diff) | |
| download | go-gemini-fbd97a62dec02ad22b7cf520cfc6ab519ea0e990.tar.xz go-gemini-fbd97a62dec02ad22b7cf520cfc6ab519ea0e990.zip | |
Refactor client certificates
Diffstat (limited to 'cert.go')
| -rw-r--r-- | cert.go | 75 |
1 files changed, 31 insertions, 44 deletions
@@ -20,9 +20,9 @@ type CertificateStore struct { store map[string]tls.Certificate } -// Add adds a certificate for the given hostname to the store. +// Add adds a certificate for the given scope to the store. // It tries to parse the certificate if it is not already parsed. -func (c *CertificateStore) Add(hostname string, cert tls.Certificate) { +func (c *CertificateStore) Add(scope string, cert tls.Certificate) { if c.store == nil { c.store = map[string]tls.Certificate{} } @@ -33,7 +33,7 @@ func (c *CertificateStore) Add(hostname string, cert tls.Certificate) { cert.Leaf = parsed } } - c.store[hostname] = cert + c.store[scope] = cert } // Lookup returns the certificate for the given hostname. @@ -49,6 +49,22 @@ 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. @@ -71,36 +87,16 @@ func (c *CertificateStore) Load(path string) error { return nil } -type ClientCertificateStore struct { - CertificateStore +// CertificateOptions configures how a certificate is created. +type CertificateOptions struct { + IPAddresses []net.IP + DNSNames []string + Duration time.Duration } -func (c *ClientCertificateStore) Lookup(hostname, urlPath string) (*tls.Certificate, error) { - urlPath = path.Clean(urlPath) - if urlPath == "." { - urlPath = "/" - } - if urlPath[0] != '/' { - urlPath = "/" + urlPath - } - for { - cert, err := c.CertificateStore.Lookup(hostname + urlPath) - switch err { - case ErrCertificateExpired, nil: - return cert, err - } - slash := urlPath == "/" - urlPath = path.Dir(urlPath) - if slash && urlPath == "/" { - break - } - } - return nil, ErrCertificateUnknown -} - -// NewCertificate creates and returns a new parsed certificate. -func NewCertificate(host string, duration time.Duration) (tls.Certificate, error) { - crt, priv, err := newX509KeyPair(host, duration) +// CreateCertificate creates a new TLS certificate. +func CreateCertificate(options CertificateOptions) (tls.Certificate, error) { + crt, priv, err := newX509KeyPair(options) if err != nil { return tls.Certificate{}, err } @@ -112,7 +108,7 @@ func NewCertificate(host string, duration time.Duration) (tls.Certificate, error } // newX509KeyPair creates and returns a new certificate and private key. -func newX509KeyPair(host string, duration time.Duration) (*x509.Certificate, crypto.PrivateKey, error) { +func newX509KeyPair(options CertificateOptions) (*x509.Certificate, crypto.PrivateKey, error) { // Generate an ED25519 private key _, priv, err := ed25519.GenerateKey(rand.Reader) if err != nil { @@ -131,7 +127,7 @@ func newX509KeyPair(host string, duration time.Duration) (*x509.Certificate, cry } notBefore := time.Now() - notAfter := notBefore.Add(duration) + notAfter := notBefore.Add(options.Duration) template := x509.Certificate{ SerialNumber: serialNumber, @@ -140,17 +136,8 @@ func newX509KeyPair(host string, duration time.Duration) (*x509.Certificate, cry KeyUsage: keyUsage, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, BasicConstraintsValid: true, - } - - if host != "" { - hosts := strings.Split(host, ",") - for _, h := range hosts { - if ip := net.ParseIP(h); ip != nil { - template.IPAddresses = append(template.IPAddresses, ip) - } else { - template.DNSNames = append(template.DNSNames, h) - } - } + IPAddresses: options.IPAddresses, + DNSNames: options.DNSNames, } crt, err := x509.CreateCertificate(rand.Reader, &template, &template, public, priv) |