summaryrefslogtreecommitdiff
path: root/src/pkg/crypto/tls
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/crypto/tls')
-rw-r--r--src/pkg/crypto/tls/common.go30
-rw-r--r--src/pkg/crypto/tls/handshake_client.go14
-rw-r--r--src/pkg/crypto/tls/handshake_server_test.go2
-rw-r--r--src/pkg/crypto/tls/root_darwin.go79
-rw-r--r--src/pkg/crypto/tls/root_stub.go10
-rw-r--r--src/pkg/crypto/tls/root_test.go37
-rw-r--r--src/pkg/crypto/tls/root_unix.go33
-rw-r--r--src/pkg/crypto/tls/root_windows.go47
-rw-r--r--src/pkg/crypto/tls/tls.go7
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