Browse code

Use exclusive root pools if a CA cert file is specified in the daemon

Signed-off-by: Ying Li <ying.li@docker.com>

Ying Li authored on 2017/05/13 03:07:51
Showing 2 changed files
... ...
@@ -129,9 +129,10 @@ func (cli *DaemonCli) start(opts daemonOptions) (err error) {
129 129
 
130 130
 	if cli.Config.TLS {
131 131
 		tlsOptions := tlsconfig.Options{
132
-			CAFile:   cli.Config.CommonTLSOptions.CAFile,
133
-			CertFile: cli.Config.CommonTLSOptions.CertFile,
134
-			KeyFile:  cli.Config.CommonTLSOptions.KeyFile,
132
+			CAFile:             cli.Config.CommonTLSOptions.CAFile,
133
+			CertFile:           cli.Config.CommonTLSOptions.CertFile,
134
+			KeyFile:            cli.Config.CommonTLSOptions.KeyFile,
135
+			ExclusiveRootPools: true,
135 136
 		}
136 137
 
137 138
 		if cli.Config.TLSVerify {
... ...
@@ -21,9 +21,14 @@ import (
21 21
 	"syscall"
22 22
 	"time"
23 23
 
24
+	"crypto/tls"
25
+	"crypto/x509"
26
+
27
+	"github.com/cloudflare/cfssl/helpers"
24 28
 	"github.com/docker/docker/integration-cli/checker"
25 29
 	"github.com/docker/docker/integration-cli/cli"
26 30
 	"github.com/docker/docker/integration-cli/daemon"
31
+	"github.com/docker/docker/opts"
27 32
 	"github.com/docker/docker/pkg/mount"
28 33
 	"github.com/docker/docker/pkg/stringid"
29 34
 	"github.com/docker/docker/pkg/testutil"
... ...
@@ -1687,7 +1692,7 @@ func (s *DockerDaemonSuite) TestDaemonStartWithoutHost(c *check.C) {
1687 1687
 }
1688 1688
 
1689 1689
 // FIXME(vdemeester) Use a new daemon instance instead of the Suite one
1690
-func (s *DockerDaemonSuite) TestDaemonStartWithDefalutTLSHost(c *check.C) {
1690
+func (s *DockerDaemonSuite) TestDaemonStartWithDefaultTLSHost(c *check.C) {
1691 1691
 	s.d.UseDefaultTLSHost = true
1692 1692
 	defer func() {
1693 1693
 		s.d.UseDefaultTLSHost = false
... ...
@@ -1717,6 +1722,33 @@ func (s *DockerDaemonSuite) TestDaemonStartWithDefalutTLSHost(c *check.C) {
1717 1717
 	if !strings.Contains(out, "Server") {
1718 1718
 		c.Fatalf("docker version should return information of server side")
1719 1719
 	}
1720
+
1721
+	// ensure when connecting to the server that only a single acceptable CA is requested
1722
+	contents, err := ioutil.ReadFile("fixtures/https/ca.pem")
1723
+	c.Assert(err, checker.IsNil)
1724
+	rootCert, err := helpers.ParseCertificatePEM(contents)
1725
+	c.Assert(err, checker.IsNil)
1726
+	rootPool := x509.NewCertPool()
1727
+	rootPool.AddCert(rootCert)
1728
+
1729
+	var certRequestInfo *tls.CertificateRequestInfo
1730
+	conn, err := tls.Dial("tcp", fmt.Sprintf("%s:%d", opts.DefaultHTTPHost, opts.DefaultTLSHTTPPort), &tls.Config{
1731
+		RootCAs: rootPool,
1732
+		GetClientCertificate: func(cri *tls.CertificateRequestInfo) (*tls.Certificate, error) {
1733
+			certRequestInfo = cri
1734
+			cert, err := tls.LoadX509KeyPair("fixtures/https/client-cert.pem", "fixtures/https/client-key.pem")
1735
+			if err != nil {
1736
+				return nil, err
1737
+			}
1738
+			return &cert, nil
1739
+		},
1740
+	})
1741
+	c.Assert(err, checker.IsNil)
1742
+	conn.Close()
1743
+
1744
+	c.Assert(certRequestInfo, checker.NotNil)
1745
+	c.Assert(certRequestInfo.AcceptableCAs, checker.HasLen, 1)
1746
+	c.Assert(certRequestInfo.AcceptableCAs[0], checker.DeepEquals, rootCert.RawSubject)
1720 1747
 }
1721 1748
 
1722 1749
 func (s *DockerDaemonSuite) TestBridgeIPIsExcludedFromAllocatorPool(c *check.C) {