diff options
Diffstat (limited to 'src/pkg/crypto/tls')
-rw-r--r-- | src/pkg/crypto/tls/common.go | 30 | ||||
-rw-r--r-- | src/pkg/crypto/tls/handshake_client.go | 14 | ||||
-rw-r--r-- | src/pkg/crypto/tls/handshake_server_test.go | 2 | ||||
-rw-r--r-- | src/pkg/crypto/tls/root_darwin.go | 79 | ||||
-rw-r--r-- | src/pkg/crypto/tls/root_stub.go | 10 | ||||
-rw-r--r-- | src/pkg/crypto/tls/root_test.go | 37 | ||||
-rw-r--r-- | src/pkg/crypto/tls/root_unix.go | 33 | ||||
-rw-r--r-- | src/pkg/crypto/tls/root_windows.go | 47 | ||||
-rw-r--r-- | src/pkg/crypto/tls/tls.go | 7 |
9 files changed, 52 insertions, 207 deletions
diff --git a/src/pkg/crypto/tls/common.go b/src/pkg/crypto/tls/common.go index 25f7a920c..4ba0bf874 100644 --- a/src/pkg/crypto/tls/common.go +++ b/src/pkg/crypto/tls/common.go @@ -198,14 +198,6 @@ func (c *Config) time() time.Time { return t() } -func (c *Config) rootCAs() *x509.CertPool { - s := c.RootCAs - if s == nil { - s = defaultRoots() - } - return s -} - func (c *Config) cipherSuites() []uint16 { s := c.CipherSuites if s == nil { @@ -311,28 +303,16 @@ func defaultConfig() *Config { return &emptyConfig } -var once sync.Once - -func defaultRoots() *x509.CertPool { - once.Do(initDefaults) - return varDefaultRoots -} +var ( + once sync.Once + varDefaultCipherSuites []uint16 +) func defaultCipherSuites() []uint16 { - once.Do(initDefaults) + once.Do(initDefaultCipherSuites) return varDefaultCipherSuites } -func initDefaults() { - initDefaultRoots() - initDefaultCipherSuites() -} - -var ( - varDefaultRoots *x509.CertPool - varDefaultCipherSuites []uint16 -) - func initDefaultCipherSuites() { varDefaultCipherSuites = make([]uint16, len(cipherSuites)) for i, suite := range cipherSuites { diff --git a/src/pkg/crypto/tls/handshake_client.go b/src/pkg/crypto/tls/handshake_client.go index 0d7b806ff..2877f1738 100644 --- a/src/pkg/crypto/tls/handshake_client.go +++ b/src/pkg/crypto/tls/handshake_client.go @@ -102,7 +102,7 @@ func (c *Conn) clientHandshake() error { if !c.config.InsecureSkipVerify { opts := x509.VerifyOptions{ - Roots: c.config.rootCAs(), + Roots: c.config.RootCAs, CurrentTime: c.config.time(), DNSName: c.config.ServerName, Intermediates: x509.NewCertPool(), @@ -166,8 +166,11 @@ func (c *Conn) clientHandshake() error { } var certToSend *Certificate + var certRequested bool certReq, ok := msg.(*certificateRequestMsg) if ok { + certRequested = true + // RFC 4346 on the certificateAuthorities field: // A list of the distinguished names of acceptable certificate // authorities. These distinguished names may specify a desired @@ -238,9 +241,14 @@ func (c *Conn) clientHandshake() error { } finishedHash.Write(shd.marshal()) - if certToSend != nil { + // If the server requested a certificate then we have to send a + // Certificate message, even if it's empty because we don't have a + // certificate to send. + if certRequested { certMsg = new(certificateMsg) - certMsg.certificates = certToSend.Certificate + if certToSend != nil { + certMsg.certificates = certToSend.Certificate + } finishedHash.Write(certMsg.marshal()) c.writeRecord(recordTypeHandshake, certMsg.marshal()) } diff --git a/src/pkg/crypto/tls/handshake_server_test.go b/src/pkg/crypto/tls/handshake_server_test.go index bd31d31ae..08a0ccb09 100644 --- a/src/pkg/crypto/tls/handshake_server_test.go +++ b/src/pkg/crypto/tls/handshake_server_test.go @@ -143,7 +143,7 @@ func testServerScript(t *testing.T, name string, serverScript [][]byte, config * if peers != nil { gotpeers := <-pchan if len(peers) == len(gotpeers) { - for i, _ := range peers { + for i := range peers { if !peers[i].Equal(gotpeers[i]) { t.Fatalf("%s: mismatch on peer cert %d", name, i) } diff --git a/src/pkg/crypto/tls/root_darwin.go b/src/pkg/crypto/tls/root_darwin.go deleted file mode 100644 index 911a9a62e..000000000 --- a/src/pkg/crypto/tls/root_darwin.go +++ /dev/null @@ -1,79 +0,0 @@ -// 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 tls - -/* -#cgo CFLAGS: -mmacosx-version-min=10.6 -D__MAC_OS_X_VERSION_MAX_ALLOWED=1060 -#cgo LDFLAGS: -framework CoreFoundation -framework Security - -#include <CoreFoundation/CoreFoundation.h> -#include <Security/Security.h> - -// FetchPEMRoots fetches the system's list of trusted X.509 root certificates. -// -// On success it returns 0 and fills pemRoots with a CFDataRef that contains the extracted root -// certificates of the system. On failure, the function returns -1. -// -// Note: The CFDataRef returned in pemRoots must be released (using CFRelease) after -// we've consumed its content. -int FetchPEMRoots(CFDataRef *pemRoots) { - if (pemRoots == NULL) { - return -1; - } - - CFArrayRef certs = NULL; - OSStatus err = SecTrustCopyAnchorCertificates(&certs); - if (err != noErr) { - return -1; - } - - CFMutableDataRef combinedData = CFDataCreateMutable(kCFAllocatorDefault, 0); - int i, ncerts = CFArrayGetCount(certs); - for (i = 0; i < ncerts; i++) { - CFDataRef data = NULL; - SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(certs, i); - if (cert == NULL) { - continue; - } - - // Note: SecKeychainItemExport is deprecated as of 10.7 in favor of SecItemExport. - // Once we support weak imports via cgo we should prefer that, and fall back to this - // for older systems. - err = SecKeychainItemExport(cert, kSecFormatX509Cert, kSecItemPemArmour, NULL, &data); - if (err != noErr) { - continue; - } - - if (data != NULL) { - CFDataAppendBytes(combinedData, CFDataGetBytePtr(data), CFDataGetLength(data)); - CFRelease(data); - } - } - - CFRelease(certs); - - *pemRoots = combinedData; - return 0; -} -*/ -import "C" -import ( - "crypto/x509" - "unsafe" -) - -func initDefaultRoots() { - roots := x509.NewCertPool() - - var data C.CFDataRef = nil - err := C.FetchPEMRoots(&data) - if err != -1 { - defer C.CFRelease(C.CFTypeRef(data)) - buf := C.GoBytes(unsafe.Pointer(C.CFDataGetBytePtr(data)), C.int(C.CFDataGetLength(data))) - roots.AppendCertsFromPEM(buf) - } - - varDefaultRoots = roots -} diff --git a/src/pkg/crypto/tls/root_stub.go b/src/pkg/crypto/tls/root_stub.go deleted file mode 100644 index ee2c3e017..000000000 --- a/src/pkg/crypto/tls/root_stub.go +++ /dev/null @@ -1,10 +0,0 @@ -// 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. - -// +build plan9 darwin,!cgo - -package tls - -func initDefaultRoots() { -} diff --git a/src/pkg/crypto/tls/root_test.go b/src/pkg/crypto/tls/root_test.go index 95a89d843..e61c21851 100644 --- a/src/pkg/crypto/tls/root_test.go +++ b/src/pkg/crypto/tls/root_test.go @@ -5,25 +5,25 @@ package tls import ( + "crypto/x509" + "runtime" "testing" ) var tlsServers = []string{ - "google.com:443", - "github.com:443", - "twitter.com:443", + "google.com", + "github.com", + "twitter.com", } func TestOSCertBundles(t *testing.T) { - defaultRoots() - if testing.Short() { t.Logf("skipping certificate tests in short mode") return } for _, addr := range tlsServers { - conn, err := Dial("tcp", addr, nil) + conn, err := Dial("tcp", addr+":443", &Config{ServerName: addr}) if err != nil { t.Errorf("unable to verify %v: %v", addr, err) continue @@ -34,3 +34,28 @@ func TestOSCertBundles(t *testing.T) { } } } + +func TestCertHostnameVerifyWindows(t *testing.T) { + if runtime.GOOS != "windows" { + return + } + + if testing.Short() { + t.Logf("skipping certificate tests in short mode") + return + } + + for _, addr := range tlsServers { + cfg := &Config{ServerName: "example.com"} + conn, err := Dial("tcp", addr+":443", cfg) + if err == nil { + conn.Close() + t.Errorf("should fail to verify for example.com: %v", addr) + continue + } + _, ok := err.(x509.HostnameError) + if !ok { + t.Errorf("error type mismatch, got: %v", err) + } + } +} diff --git a/src/pkg/crypto/tls/root_unix.go b/src/pkg/crypto/tls/root_unix.go deleted file mode 100644 index acaf3dd9d..000000000 --- a/src/pkg/crypto/tls/root_unix.go +++ /dev/null @@ -1,33 +0,0 @@ -// 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. - -// +build freebsd linux openbsd netbsd - -package tls - -import ( - "crypto/x509" - "io/ioutil" -) - -// Possible certificate files; stop after finding one. -var certFiles = []string{ - "/etc/ssl/certs/ca-certificates.crt", // Linux etc - "/etc/pki/tls/certs/ca-bundle.crt", // Fedora/RHEL - "/etc/ssl/ca-bundle.pem", // OpenSUSE - "/etc/ssl/cert.pem", // OpenBSD - "/usr/local/share/certs/ca-root-nss.crt", // FreeBSD -} - -func initDefaultRoots() { - roots := x509.NewCertPool() - for _, file := range certFiles { - data, err := ioutil.ReadFile(file) - if err == nil { - roots.AppendCertsFromPEM(data) - break - } - } - varDefaultRoots = roots -} diff --git a/src/pkg/crypto/tls/root_windows.go b/src/pkg/crypto/tls/root_windows.go deleted file mode 100644 index 319309ae6..000000000 --- a/src/pkg/crypto/tls/root_windows.go +++ /dev/null @@ -1,47 +0,0 @@ -// 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 tls - -import ( - "crypto/x509" - "syscall" - "unsafe" -) - -func loadStore(roots *x509.CertPool, name string) { - store, err := syscall.CertOpenSystemStore(syscall.InvalidHandle, syscall.StringToUTF16Ptr(name)) - if err != nil { - return - } - defer syscall.CertCloseStore(store, 0) - - var cert *syscall.CertContext - for { - cert, err = syscall.CertEnumCertificatesInStore(store, cert) - if err != nil { - return - } - - buf := (*[1 << 20]byte)(unsafe.Pointer(cert.EncodedCert))[:] - // ParseCertificate requires its own copy of certificate data to keep. - buf2 := make([]byte, cert.Length) - copy(buf2, buf) - if c, err := x509.ParseCertificate(buf2); err == nil { - roots.AddCert(c) - } - } -} - -func initDefaultRoots() { - roots := x509.NewCertPool() - - // Roots - loadStore(roots, "ROOT") - - // Intermediates - loadStore(roots, "CA") - - varDefaultRoots = roots -} diff --git a/src/pkg/crypto/tls/tls.go b/src/pkg/crypto/tls/tls.go index 9184e8e81..09df5ad44 100644 --- a/src/pkg/crypto/tls/tls.go +++ b/src/pkg/crypto/tls/tls.go @@ -2,8 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Package tls partially implements the TLS 1.1 protocol, as specified in RFC -// 4346. +// Package tls partially implements TLS 1.0, as specified in RFC 2246. package tls import ( @@ -98,7 +97,9 @@ func Dial(network, addr string, config *Config) (*Conn, error) { if config == nil { config = defaultConfig() } - if config.ServerName != "" { + // If no ServerName is set, infer the ServerName + // from the hostname we're connecting to. + if config.ServerName == "" { // Make a copy to avoid polluting argument or default. c := *config c.ServerName = hostname |