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 }