prf.go\
tls.go\
+ifeq ($(CGO_ENABLED),1)
+CGOFILES_darwin=\
+ root_darwin.go
+else
+GOFILES_darwin+=root_stub.go
+endif
+
+GOFILES_freebsd+=root_unix.go
+GOFILES_linux+=root_unix.go
+GOFILES_openbsd+=root_unix.go
+GOFILES_plan9+=root_stub.go
+GOFILES_windows+=root_stub.go
+
+GOFILES+=$(GOFILES_$(GOOS))
+ifneq ($(CGOFILES_$(GOOS)),)
+CGOFILES+=$(CGOFILES_$(GOOS))
+endif
+
include ../../../Make.pkg
"crypto/rsa"
"crypto/x509"
"io"
- "io/ioutil"
"strings"
"sync"
"time"
// anything more than self-signed.
AuthenticateClient bool
+ // InsecureSkipVerify controls whether a client verifies the
+ // server's certificate chain and host name.
+ // If InsecureSkipVerify is true, TLS accepts any certificate
+ // presented by the server and any host name in that certificate.
+ // In this mode, TLS is susceptible to man-in-the-middle attacks.
+ // This should be used only for testing.
+ InsecureSkipVerify bool
+
// CipherSuites is a list of supported cipher suites. If CipherSuites
// is nil, TLS uses a list of suites supported by the implementation.
CipherSuites []uint16
return &emptyConfig
}
-// Possible certificate files; stop after finding one.
-// On OS X we should really be using the Directory Services keychain
-// but that requires a lot of Mach goo to get at. Instead we use
-// the same root set that curl uses.
-var certFiles = []string{
- "/etc/ssl/certs/ca-certificates.crt", // Linux etc
- "/usr/share/curl/curl-ca-bundle.crt", // OS X
-}
-
var once sync.Once
func defaultRoots() *x509.CertPool {
initDefaultCipherSuites()
}
-var varDefaultRoots *x509.CertPool
-
-func initDefaultRoots() {
- roots := x509.NewCertPool()
- for _, file := range certFiles {
- data, err := ioutil.ReadFile(file)
- if err == nil {
- roots.AppendCertsFromPEM(data)
- break
- }
- }
- varDefaultRoots = roots
-}
-
-var varDefaultCipherSuites []uint16
+var (
+ varDefaultRoots *x509.CertPool
+ varDefaultCipherSuites []uint16
+)
func initDefaultCipherSuites() {
varDefaultCipherSuites = make([]uint16, len(cipherSuites))
certs[i] = cert
}
- // If we don't have a root CA set configured then anything is accepted.
- // TODO(rsc): Find certificates for OS X 10.6.
- if c.config.RootCAs != nil {
+ 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(),
testConfig.Certificates[0].Certificate = [][]byte{testCertificate}
testConfig.Certificates[0].PrivateKey = testPrivateKey
testConfig.CipherSuites = []uint16{TLS_RSA_WITH_RC4_128_SHA}
+ testConfig.InsecureSkipVerify = true
}
func testClientHelloFailure(t *testing.T, m handshakeMessage, expected os.Error) {
--- /dev/null
+// 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
+
+/*
+// Note: We disable -Werror here because the code in this file uses a deprecated API to stay
+// compatible with both Mac OS X 10.6 and 10.7. Using a deprecated function on Darwin generates
+// a warning.
+#cgo CFLAGS: -Wno-error
+#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;
+ }
+
+ // SecKeychainImportExport is deprecated in >= OS X 10.7, and has been replaced by
+ // SecItemExport. If we're built on a host with a Lion SDK, this code gets conditionally
+ // included in the output, also for binaries meant for 10.6.
+ //
+ // To make sure that we run on both Mac OS X 10.6 and 10.7 we use weak linking
+ // and check whether SecItemExport is available before we attempt to call it. On
+ // 10.6, this won't be the case, and we'll fall back to calling SecKeychainItemExport.
+#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
+ if (SecItemExport) {
+ err = SecItemExport(cert, kSecFormatX509Cert, kSecItemPemArmour, NULL, &data);
+ if (err != noErr) {
+ continue;
+ }
+ } else
+#endif
+ if (data == NULL) {
+ 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
+}
--- /dev/null
+// 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
+
+func initDefaultRoots() {
+}
--- /dev/null
+// 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 (
+ "testing"
+)
+
+var tlsServers = []string{
+ "google.com:443",
+ "github.com:443",
+ "twitter.com:443",
+}
+
+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)
+ if err != nil {
+ t.Errorf("unable to verify %v: %v", addr, err)
+ continue
+ }
+ err = conn.Close()
+ if err != nil {
+ t.Error(err)
+ }
+ }
+}
--- /dev/null
+// 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"
+ "io/ioutil"
+)
+
+// Possible certificate files; stop after finding one.
+var certFiles = []string{
+ "/etc/ssl/certs/ca-certificates.crt", // Linux etc
+}
+
+func initDefaultRoots() {
+ roots := x509.NewCertPool()
+ for _, file := range certFiles {
+ data, err := ioutil.ReadFile(file)
+ if err == nil {
+ roots.AppendCertsFromPEM(data)
+ break
+ }
+ }
+ varDefaultRoots = roots
+}
import (
"bufio"
"bytes"
+ "crypto/tls"
"fmt"
. "http"
"http/httptest"
"io"
"io/ioutil"
"log"
- "os"
"net"
+ "os"
"reflect"
"strings"
"syscall"
t.Errorf("expected test TLS server to start with https://, got %q", ts.URL)
return
}
- res, err := Get(ts.URL)
+ noVerifyTransport := &Transport{
+ TLSClientConfig: &tls.Config{
+ InsecureSkipVerify: true,
+ },
+ }
+ client := &Client{Transport: noVerifyTransport}
+ res, err := client.Get(ts.URL)
if err != nil {
t.Error(err)
return