func (h HostnameError) Error() string {
c := h.Certificate
+ maxNamesIncluded := 100
if !c.hasSANExtension() && matchHostnames(c.Subject.CommonName, h.Host) {
return "x509: certificate relies on legacy Common Name field, use SANs instead"
}
- var valid string
+ var valid strings.Builder
if ip := net.ParseIP(h.Host); ip != nil {
// Trying to validate an IP
if len(c.IPAddresses) == 0 {
return "x509: cannot validate certificate for " + h.Host + " because it doesn't contain any IP SANs"
}
+ if len(c.IPAddresses) >= maxNamesIncluded {
+ return fmt.Sprintf("x509: certificate is valid for %d IP SANs, but none matched %s", len(c.IPAddresses), h.Host)
+ }
for _, san := range c.IPAddresses {
- if len(valid) > 0 {
- valid += ", "
+ if valid.Len() > 0 {
+ valid.WriteString(", ")
}
- valid += san.String()
+ valid.WriteString(san.String())
}
} else {
- valid = strings.Join(c.DNSNames, ", ")
+ if len(c.DNSNames) >= maxNamesIncluded {
+ return fmt.Sprintf("x509: certificate is valid for %d names, but none matched %s", len(c.DNSNames), h.Host)
+ }
+ valid.WriteString(strings.Join(c.DNSNames, ", "))
}
- if len(valid) == 0 {
+ if valid.Len() == 0 {
return "x509: certificate is not valid for any names, but wanted to match " + h.Host
}
- return "x509: certificate is valid for " + valid + ", not " + h.Host
+ return "x509: certificate is valid for " + valid.String() + ", not " + h.Host
}
// UnknownAuthorityError results when the certificate issuer is unknown
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
+ "crypto/rsa"
"crypto/x509/pkix"
"encoding/asn1"
"encoding/pem"
"errors"
"fmt"
"internal/testenv"
+ "log"
"math/big"
+ "net"
"os"
"os/exec"
"runtime"
errorCallback: expectHostnameError("certificate is valid for"),
},
+ {
+ name: "TooManyDNS",
+ leaf: generatePEMCertWithRepeatSAN(1677615892, 200, "fake.dns"),
+ roots: []string{generatePEMCertWithRepeatSAN(1677615892, 200, "fake.dns")},
+ currentTime: 1677615892,
+ dnsName: "www.example.com",
+ systemSkip: true, // does not chain to a system root
+
+ errorCallback: expectHostnameError("certificate is valid for 200 names, but none matched"),
+ },
+ {
+ name: "TooManyIPs",
+ leaf: generatePEMCertWithRepeatSAN(1677615892, 150, "4.3.2.1"),
+ roots: []string{generatePEMCertWithRepeatSAN(1677615892, 150, "4.3.2.1")},
+ currentTime: 1677615892,
+ dnsName: "1.2.3.4",
+ systemSkip: true, // does not chain to a system root
+
+ errorCallback: expectHostnameError("certificate is valid for 150 IP SANs, but none matched"),
+ },
{
name: "IPMissing",
leaf: googleLeaf,
return strings.Join(name.Country, ",") + "/" + strings.Join(name.Organization, ",") + "/" + strings.Join(name.OrganizationalUnit, ",") + "/" + name.CommonName
}
+func generatePEMCertWithRepeatSAN(currentTime int64, count int, san string) string {
+ cert := Certificate{
+ NotBefore: time.Unix(currentTime, 0),
+ NotAfter: time.Unix(currentTime, 0),
+ }
+ if ip := net.ParseIP(san); ip != nil {
+ cert.IPAddresses = slices.Repeat([]net.IP{ip}, count)
+ } else {
+ cert.DNSNames = slices.Repeat([]string{san}, count)
+ }
+ privKey, err := rsa.GenerateKey(rand.Reader, 4096)
+ if err != nil {
+ log.Fatal(err)
+ }
+ certBytes, err := CreateCertificate(rand.Reader, &cert, &cert, &privKey.PublicKey, privKey)
+ if err != nil {
+ log.Fatal(err)
+ }
+ return string(pem.EncodeToMemory(&pem.Block{
+ Type: "CERTIFICATE",
+ Bytes: certBytes,
+ }))
+}
+
const gtsIntermediate = `-----BEGIN CERTIFICATE-----
MIIFljCCA36gAwIBAgINAgO8U1lrNMcY9QFQZjANBgkqhkiG9w0BAQsFADBHMQsw
CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU