mirror of
https://github.com/pomerium/pomerium.git
synced 2025-04-29 18:36:30 +02:00
* envoy: support autocert * envoy: fallback to http host routing if sni fails to match * update comment * envoy: renew certs when necessary * fix tests
51 lines
1.2 KiB
Go
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
|
|
}
|