aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdnan Maolood <[email protected]>2021-02-28 20:23:29 -0500
committerAdnan Maolood <[email protected]>2021-02-28 20:23:32 -0500
commitcf9ab18c1f30b0d2d58d0914fa777ffa90ccea2d (patch)
tree02c29ef5aa0c17a1fa1fb163e0a5f63c3eda08b5
parentcertificate.Store: Support client certificates (diff)
downloadgo-gemini-cf9ab18c1f30b0d2d58d0914fa777ffa90ccea2d.tar.xz
go-gemini-cf9ab18c1f30b0d2d58d0914fa777ffa90ccea2d.zip
certificate.Store: Check parent scopes in Lookup
-rw-r--r--certificate/store.go19
1 files changed, 18 insertions, 1 deletions
diff --git a/certificate/store.go b/certificate/store.go
index 6baab80..fd07ffe 100644
--- a/certificate/store.go
+++ b/certificate/store.go
@@ -8,6 +8,7 @@ import (
"fmt"
"io/fs"
"os"
+ "path"
"path/filepath"
"strings"
"sync"
@@ -22,7 +23,8 @@ import (
// Servers will most likely use the methods Register, Load and Get.
//
// Store can also be used to store client certificates.
-// Clients should provide the hostname and path of a URL as a certificate scope.
+// Clients should provide the hostname and path of a URL as a certificate scope
+// (without a trailing slash).
// Clients will most likely use the methods Add, Load, and Lookup.
//
// Store is safe for concurrent use by multiple goroutines.
@@ -140,10 +142,25 @@ func (s *Store) Get(hostname string) (*tls.Certificate, error) {
}
// Lookup returns the certificate for the provided scope.
+// Lookup also checks for certificates in parent scopes.
+// For example, given the scope "example.com/a/b/c", Lookup will first check
+// "example.com/a/b/c", then "example.com/a/b", then "example.com/a", and
+// finally "example.com" for a certificate. As a result, a certificate with
+// scope "example.com" will match all scopes beginning with "example.com".
func (s *Store) Lookup(scope string) (tls.Certificate, bool) {
s.mu.RLock()
defer s.mu.RUnlock()
cert, ok := s.certs[scope]
+ if !ok {
+ scope = path.Dir(scope)
+ for scope != "." {
+ cert, ok = s.certs[scope]
+ if ok {
+ break
+ }
+ scope = path.Dir(scope)
+ }
+ }
return cert, ok
}