aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdnan Maolood <[email protected]>2021-03-04 14:36:31 -0500
committerAdnan Maolood <[email protected]>2021-03-04 14:36:31 -0500
commitbfa3356d3a307afdc8303f2e4cfe0d65c4befbde (patch)
tree940d6cb6ca5744dbc093025dade5c2e05a9feca9
parentclient: Ignore certificate expiration time (diff)
downloadgo-gemini-bfa3356d3a307afdc8303f2e4cfe0d65c4befbde.tar.xz
go-gemini-bfa3356d3a307afdc8303f2e4cfe0d65c4befbde.zip
client: Remove hostname verification check
-rw-r--r--client.go4
-rw-r--r--verify_hostname.go212
2 files changed, 0 insertions, 216 deletions
diff --git a/client.go b/client.go
index 2a26a63..7b577a8 100644
--- a/client.go
+++ b/client.go
@@ -175,10 +175,6 @@ func (c *Client) dialContext(ctx context.Context, network, addr string) (net.Con
func (c *Client) verifyConnection(cs tls.ConnectionState, hostname string) error {
cert := cs.PeerCertificates[0]
- // Verify hostname
- if err := verifyHostname(cert, hostname); err != nil {
- return err
- }
// See if the client trusts the certificate
if c.TrustCertificate != nil {
return c.TrustCertificate(hostname, cert)
diff --git a/verify_hostname.go b/verify_hostname.go
deleted file mode 100644
index 99e11b3..0000000
--- a/verify_hostname.go
+++ /dev/null
@@ -1,212 +0,0 @@
-// Hostname verification code from the crypto/x509 package.
-// Modified to allow Common Names in the short term, until new certificates
-// can be issued with SANs.
-
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package gemini
-
-import (
- "crypto/x509"
- "net"
- "strings"
- "unicode/utf8"
-)
-
-var oidExtensionSubjectAltName = []int{2, 5, 29, 17}
-
-func hasSANExtension(c *x509.Certificate) bool {
- for _, e := range c.Extensions {
- if e.Id.Equal(oidExtensionSubjectAltName) {
- return true
- }
- }
- return false
-}
-
-func validHostnamePattern(host string) bool { return validHostname(host, true) }
-func validHostnameInput(host string) bool { return validHostname(host, false) }
-
-// validHostname reports whether host is a valid hostname that can be matched or
-// matched against according to RFC 6125 2.2, with some leniency to accommodate
-// legacy values.
-func validHostname(host string, isPattern bool) bool {
- if !isPattern {
- host = strings.TrimSuffix(host, ".")
- }
- if len(host) == 0 {
- return false
- }
-
- for i, part := range strings.Split(host, ".") {
- if part == "" {
- // Empty label.
- return false
- }
- if isPattern && i == 0 && part == "*" {
- // Only allow full left-most wildcards, as those are the only ones
- // we match, and matching literal '*' characters is probably never
- // the expected behavior.
- continue
- }
- for j, c := range part {
- if 'a' <= c && c <= 'z' {
- continue
- }
- if '0' <= c && c <= '9' {
- continue
- }
- if 'A' <= c && c <= 'Z' {
- continue
- }
- if c == '-' && j != 0 {
- continue
- }
- if c == '_' {
- // Not a valid character in hostnames, but commonly
- // found in deployments outside the WebPKI.
- continue
- }
- return false
- }
- }
-
- return true
-}
-
-// commonNameAsHostname reports whether the Common Name field should be
-// considered the hostname that the certificate is valid for. This is a legacy
-// behavior, disabled by default or if the Subject Alt Name extension is present.
-//
-// It applies the strict validHostname check to the Common Name field, so that
-// certificates without SANs can still be validated against CAs with name
-// constraints if there is no risk the CN would be matched as a hostname.
-// See NameConstraintsWithoutSANs and issue 24151.
-func commonNameAsHostname(c *x509.Certificate) bool {
- return !hasSANExtension(c) && validHostnamePattern(c.Subject.CommonName)
-}
-
-func matchExactly(hostA, hostB string) bool {
- if hostA == "" || hostA == "." || hostB == "" || hostB == "." {
- return false
- }
- return toLowerCaseASCII(hostA) == toLowerCaseASCII(hostB)
-}
-
-func matchHostnames(pattern, host string) bool {
- pattern = toLowerCaseASCII(pattern)
- host = toLowerCaseASCII(strings.TrimSuffix(host, "."))
-
- if len(pattern) == 0 || len(host) == 0 {
- return false
- }
-
- patternParts := strings.Split(pattern, ".")
- hostParts := strings.Split(host, ".")
-
- if len(patternParts) != len(hostParts) {
- return false
- }
-
- for i, patternPart := range patternParts {
- if i == 0 && patternPart == "*" {
- continue
- }
- if patternPart != hostParts[i] {
- return false
- }
- }
-
- return true
-}
-
-// toLowerCaseASCII returns a lower-case version of in. See RFC 6125 6.4.1. We use
-// an explicitly ASCII function to avoid any sharp corners resulting from
-// performing Unicode operations on DNS labels.
-func toLowerCaseASCII(in string) string {
- // If the string is already lower-case then there's nothing to do.
- isAlreadyLowerCase := true
- for _, c := range in {
- if c == utf8.RuneError {
- // If we get a UTF-8 error then there might be
- // upper-case ASCII bytes in the invalid sequence.
- isAlreadyLowerCase = false
- break
- }
- if 'A' <= c && c <= 'Z' {
- isAlreadyLowerCase = false
- break
- }
- }
-
- if isAlreadyLowerCase {
- return in
- }
-
- out := []byte(in)
- for i, c := range out {
- if 'A' <= c && c <= 'Z' {
- out[i] += 'a' - 'A'
- }
- }
- return string(out)
-}
-
-// verifyHostname returns nil if c is a valid certificate for the named host.
-// Otherwise it returns an error describing the mismatch.
-//
-// IP addresses can be optionally enclosed in square brackets and are checked
-// against the IPAddresses field. Other names are checked case insensitively
-// against the DNSNames field. If the names are valid hostnames, the certificate
-// fields can have a wildcard as the left-most label.
-//
-// The legacy Common Name field is ignored unless it's a valid hostname, the
-// certificate doesn't have any Subject Alternative Names, and the GODEBUG
-// environment variable is set to "x509ignoreCN=0". Support for Common Name is
-// deprecated will be entirely removed in the future.
-func verifyHostname(c *x509.Certificate, h string) error {
- // IP addresses may be written in [ ].
- candidateIP := h
- if len(h) >= 3 && h[0] == '[' && h[len(h)-1] == ']' {
- candidateIP = h[1 : len(h)-1]
- }
- if ip := net.ParseIP(candidateIP); ip != nil {
- // We only match IP addresses against IP SANs.
- // See RFC 6125, Appendix B.2.
- for _, candidate := range c.IPAddresses {
- if ip.Equal(candidate) {
- return nil
- }
- }
- return x509.HostnameError{c, candidateIP}
- }
-
- names := c.DNSNames
- if commonNameAsHostname(c) {
- names = []string{c.Subject.CommonName}
- }
-
- candidateName := toLowerCaseASCII(h) // Save allocations inside the loop.
- validCandidateName := validHostnameInput(candidateName)
-
- for _, match := range names {
- // Ideally, we'd only match valid hostnames according to RFC 6125 like
- // browsers (more or less) do, but in practice Go is used in a wider
- // array of contexts and can't even assume DNS resolution. Instead,
- // always allow perfect matches, and only apply wildcard and trailing
- // dot processing to valid hostnames.
- if validCandidateName && validHostnamePattern(match) {
- if matchHostnames(match, candidateName) {
- return nil
- }
- } else {
- if matchExactly(match, candidateName) {
- return nil
- }
- }
- }
-
- return x509.HostnameError{c, h}
-}