forked from pomerium/ingress-controller
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
wasaga
committed
Aug 19, 2021
1 parent
4010c11
commit e9c2302
Showing
7 changed files
with
251 additions
and
79 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
package pomerium | ||
|
||
import ( | ||
"crypto/x509" | ||
"encoding/pem" | ||
"fmt" | ||
"strings" | ||
|
||
pb "github.com/pomerium/pomerium/pkg/grpc/config" | ||
) | ||
|
||
type domainKey struct { | ||
Host, Domain string | ||
} | ||
|
||
func parseDomainKey(dnsName string) domainKey { | ||
parts := strings.SplitN(dnsName, ".", 2) | ||
if len(parts) != 2 { | ||
return domainKey{Host: dnsName} | ||
} | ||
return domainKey{Host: parts[0], Domain: parts[1]} | ||
} | ||
|
||
type certRef struct { | ||
inUse bool | ||
data *pb.Settings_Certificate | ||
cert *x509.Certificate | ||
} | ||
|
||
func parseCert(cert *pb.Settings_Certificate) (*x509.Certificate, error) { | ||
block, _ := pem.Decode(cert.CertBytes) | ||
if block == nil { | ||
return nil, fmt.Errorf("failed to decode cert block") | ||
} | ||
|
||
if block.Type != "CERTIFICATE" { | ||
return nil, fmt.Errorf("expected CERTIFICATE PEM block, got %q", block.Type) | ||
} | ||
|
||
return x509.ParseCertificate(block.Bytes) | ||
} | ||
|
||
type domainMap map[domainKey]*certRef | ||
|
||
func toDomainMap(certs []*pb.Settings_Certificate) (domainMap, error) { | ||
domains := make(domainMap) | ||
for _, cert := range certs { | ||
crt, err := parseCert(cert) | ||
if err != nil { | ||
return nil, err | ||
} | ||
domains.add(cert, crt) | ||
} | ||
return domains, nil | ||
} | ||
|
||
func (dm domainMap) getCertsInUse() []*pb.Settings_Certificate { | ||
certMap := make(map[*pb.Settings_Certificate]struct{}) | ||
for _, ref := range dm { | ||
if ref.inUse { | ||
certMap[ref.data] = struct{}{} | ||
} | ||
} | ||
certs := make([]*pb.Settings_Certificate, 0, len(certMap)) | ||
for crt := range certMap { | ||
certs = append(certs, crt) | ||
} | ||
return certs | ||
} | ||
|
||
func (dm domainMap) addIfNewer(key domainKey, ref *certRef) { | ||
cur := dm[key] | ||
if cur == nil { | ||
dm[key] = ref | ||
return | ||
} | ||
if cur.cert.NotAfter.Before(ref.cert.NotAfter) { | ||
dm[key] = ref | ||
} | ||
} | ||
|
||
func (dm domainMap) add(data *pb.Settings_Certificate, cert *x509.Certificate) { | ||
ref := &certRef{ | ||
inUse: false, | ||
data: data, | ||
cert: cert, | ||
} | ||
for _, name := range cert.DNSNames { | ||
dm.addIfNewer(parseDomainKey(name), ref) | ||
} | ||
} | ||
|
||
func (dm domainMap) markInUse(dnsName string) { | ||
key := parseDomainKey(dnsName) | ||
if ref := dm[key]; ref != nil { | ||
ref.inUse = true | ||
return | ||
} | ||
if ref := dm[domainKey{Host: "*", Domain: key.Domain}]; ref != nil { | ||
ref.inUse = true | ||
} | ||
} |
Oops, something went wrong.