pomerium/internal/cryptutil/tls.go
Caleb Doxsey dccec1e646 envoy: support autocert (#695)
* envoy: support autocert

* envoy: fallback to http host routing if sni fails to match

* update comment

* envoy: renew certs when necessary

* fix tests
2020-05-18 17:10:10 -04:00

51 lines
1.2 KiB
Go

package cryptutil
import (
"crypto/tls"
"crypto/x509"
"github.com/caddyserver/certmagic"
)
// GetCertificateForDomain returns the tls Certificate which matches the given domain name.
// It should handle both exact matches and wildcard matches. If none of those match, the first certificate will be used.
// Finally if there are no matching certificates one will be generated.
func GetCertificateForDomain(certificates []tls.Certificate, domain string) (*tls.Certificate, error) {
// first try a direct name match
for _, cert := range certificates {
if matchesDomain(&cert, domain) {
return &cert, nil
}
}
// next use the first cert
if len(certificates) > 0 {
return &certificates[0], nil
}
// finally fall back to a generated, self-signed certificate
return GenerateSelfSignedCertificate(domain)
}
func matchesDomain(cert *tls.Certificate, domain string) bool {
if cert == nil || len(cert.Certificate) == 0 {
return false
}
xcert, err := x509.ParseCertificate(cert.Certificate[0])
if err != nil {
return false
}
if certmagic.MatchWildcard(domain, xcert.Subject.CommonName) {
return true
}
for _, san := range xcert.DNSNames {
if certmagic.MatchWildcard(domain, san) {
return true
}
}
return false
}