github.com/juju/juju@v0.0.0-20240327075706-a90865de2538/worker/httpserver/tls_state_test.go (about)

     1  // Copyright 2018 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package httpserver_test
     5  
     6  import (
     7  	"crypto/tls"
     8  	"crypto/x509"
     9  	"net/http"
    10  	"net/http/httptest"
    11  
    12  	"github.com/juju/loggo"
    13  	jc "github.com/juju/testing/checkers"
    14  	"golang.org/x/crypto/acme"
    15  	gc "gopkg.in/check.v1"
    16  
    17  	"github.com/juju/juju/worker/httpserver"
    18  )
    19  
    20  type tlsStateFixture struct {
    21  	stateFixture
    22  	cert *tls.Certificate
    23  }
    24  
    25  func (s *tlsStateFixture) SetUpTest(c *gc.C) {
    26  	s.stateFixture.SetUpTest(c)
    27  	s.cert = &tls.Certificate{
    28  		Leaf: &x509.Certificate{
    29  			DNSNames: []string{
    30  				"testing1.invalid",
    31  				"testing2.invalid",
    32  				"testing3.invalid",
    33  			},
    34  		},
    35  	}
    36  }
    37  
    38  type TLSStateSuite struct {
    39  	tlsStateFixture
    40  }
    41  
    42  var _ = gc.Suite(&TLSStateSuite{})
    43  
    44  func (s *TLSStateSuite) TestNewTLSConfig(c *gc.C) {
    45  	tlsConfig, err := httpserver.NewTLSConfig(
    46  		s.State,
    47  		testSNIGetter(s.cert),
    48  		loggo.GetLogger("test"),
    49  	)
    50  	c.Assert(err, jc.ErrorIsNil)
    51  
    52  	cert, err := tlsConfig.GetCertificate(&tls.ClientHelloInfo{
    53  		ServerName: "anything.invalid",
    54  	})
    55  	c.Assert(err, jc.ErrorIsNil)
    56  	c.Assert(cert, gc.Equals, s.cert)
    57  }
    58  
    59  type TLSStateAutocertSuite struct {
    60  	tlsStateFixture
    61  	autocertQueried bool
    62  }
    63  
    64  var _ = gc.Suite(&TLSStateAutocertSuite{})
    65  
    66  func (s *TLSStateAutocertSuite) SetUpSuite(c *gc.C) {
    67  	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    68  		s.autocertQueried = true
    69  		http.Error(w, "burp", http.StatusUnavailableForLegalReasons)
    70  	}))
    71  	s.ControllerConfig = map[string]interface{}{
    72  		"autocert-dns-name": "public.invalid",
    73  		"autocert-url":      server.URL,
    74  	}
    75  	s.tlsStateFixture.SetUpSuite(c)
    76  	s.AddCleanup(func(c *gc.C) { server.Close() })
    77  }
    78  
    79  func (s *TLSStateAutocertSuite) SetUpTest(c *gc.C) {
    80  	s.tlsStateFixture.SetUpTest(c)
    81  	s.autocertQueried = false
    82  }
    83  
    84  func (s *TLSStateAutocertSuite) TestAutocertExceptions(c *gc.C) {
    85  	tlsConfig, err := httpserver.NewTLSConfig(
    86  		s.State,
    87  		testSNIGetter(s.cert),
    88  		loggo.GetLogger("test"),
    89  	)
    90  	c.Assert(err, jc.ErrorIsNil)
    91  	s.testGetCertificate(c, tlsConfig, "127.0.0.1")
    92  	s.testGetCertificate(c, tlsConfig, "juju-apiserver")
    93  	s.testGetCertificate(c, tlsConfig, "testing1.invalid")
    94  	c.Assert(s.autocertQueried, jc.IsFalse)
    95  }
    96  
    97  func (s *TLSStateAutocertSuite) TestAutocert(c *gc.C) {
    98  	tlsConfig, err := httpserver.NewTLSConfig(
    99  		s.State,
   100  		testSNIGetter(s.cert),
   101  		loggo.GetLogger("test"),
   102  	)
   103  	c.Assert(err, jc.ErrorIsNil)
   104  	s.testGetCertificate(c, tlsConfig, "public.invalid")
   105  	c.Assert(s.autocertQueried, jc.IsTrue)
   106  	c.Assert(tlsConfig.NextProtos, jc.DeepEquals, []string{"h2", "http/1.1", acme.ALPNProto})
   107  }
   108  
   109  func (s *TLSStateAutocertSuite) TestAutocertHostPolicy(c *gc.C) {
   110  	tlsConfig, err := httpserver.NewTLSConfig(
   111  		s.State,
   112  		testSNIGetter(s.cert),
   113  		loggo.GetLogger("test"),
   114  	)
   115  	c.Assert(err, jc.ErrorIsNil)
   116  	s.testGetCertificate(c, tlsConfig, "always.invalid")
   117  	c.Assert(s.autocertQueried, jc.IsFalse)
   118  }
   119  
   120  func (s *TLSStateAutocertSuite) testGetCertificate(c *gc.C, tlsConfig *tls.Config, serverName string) {
   121  	cert, err := tlsConfig.GetCertificate(&tls.ClientHelloInfo{
   122  		ServerName: serverName,
   123  	})
   124  	c.Assert(err, jc.ErrorIsNil, gc.Commentf("server name %q", serverName))
   125  	// NOTE(axw) we always expect to get back s.cert, because we don't have
   126  	// a functioning autocert test server. We do check that we attempt to
   127  	// query the autocert server, but that's as far as we test here.
   128  	c.Assert(cert, gc.Equals, s.cert, gc.Commentf("server name %q", serverName))
   129  }