Commit 8efb3044 authored by Adam Langley's avatar Adam Langley

crypto/x509: use case-insensitive hostname matching.

Fixes #2792.

R=golang-dev, r
CC=golang-dev
https://golang.org/cl/5590045
parent 2d64bab1
...@@ -7,6 +7,7 @@ package x509 ...@@ -7,6 +7,7 @@ package x509
import ( import (
"strings" "strings"
"time" "time"
"unicode/utf8"
) )
type InvalidReason int type InvalidReason int
...@@ -225,17 +226,51 @@ func matchHostnames(pattern, host string) bool { ...@@ -225,17 +226,51 @@ func matchHostnames(pattern, host string) bool {
return true 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. // VerifyHostname returns nil if c is a valid certificate for the named host.
// Otherwise it returns an error describing the mismatch. // Otherwise it returns an error describing the mismatch.
func (c *Certificate) VerifyHostname(h string) error { func (c *Certificate) VerifyHostname(h string) error {
lowered := toLowerCaseASCII(h)
if len(c.DNSNames) > 0 { if len(c.DNSNames) > 0 {
for _, match := range c.DNSNames { for _, match := range c.DNSNames {
if matchHostnames(match, h) { if matchHostnames(toLowerCaseASCII(match), lowered) {
return nil return nil
} }
} }
// If Subject Alt Name is given, we ignore the common name. // If Subject Alt Name is given, we ignore the common name.
} else if matchHostnames(c.Subject.CommonName, h) { } else if matchHostnames(toLowerCaseASCII(c.Subject.CommonName), lowered) {
return nil return nil
} }
......
...@@ -37,6 +37,17 @@ var verifyTests = []verifyTest{ ...@@ -37,6 +37,17 @@ var verifyTests = []verifyTest{
{"Google", "Thawte", "VeriSign"}, {"Google", "Thawte", "VeriSign"},
}, },
}, },
{
leaf: googleLeaf,
intermediates: []string{thawteIntermediate},
roots: []string{verisignRoot},
currentTime: 1302726541,
dnsName: "WwW.GooGLE.coM",
expectedChains: [][]string{
{"Google", "Thawte", "VeriSign"},
},
},
{ {
leaf: googleLeaf, leaf: googleLeaf,
intermediates: []string{thawteIntermediate}, intermediates: []string{thawteIntermediate},
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment