transport_test.go 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. /*
  2. Copyright 2017 The Kubernetes Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package certificate
  14. import (
  15. "crypto/tls"
  16. "crypto/x509"
  17. "fmt"
  18. "math/big"
  19. "net/http"
  20. "net/http/httptest"
  21. "sync/atomic"
  22. "testing"
  23. "time"
  24. "k8s.io/apimachinery/pkg/runtime"
  25. "k8s.io/apimachinery/pkg/runtime/serializer"
  26. certificatesclient "k8s.io/client-go/kubernetes/typed/certificates/v1beta1"
  27. "k8s.io/client-go/rest"
  28. )
  29. var (
  30. client1CertData = newCertificateData(`-----BEGIN CERTIFICATE-----
  31. MIICBDCCAW2gAwIBAgIJAPgVBh+4xbGoMA0GCSqGSIb3DQEBCwUAMBsxGTAXBgNV
  32. BAMMEHdlYmhvb2tfdGVzdHNfY2EwIBcNMTcwNzI4MjMxNTI4WhgPMjI5MTA1MTMy
  33. MzE1MjhaMB8xHTAbBgNVBAMMFHdlYmhvb2tfdGVzdHNfY2xpZW50MIGfMA0GCSqG
  34. SIb3DQEBAQUAA4GNADCBiQKBgQDkGXXSm6Yun5o3Jlmx45rItcQ2pmnoDk4eZfl0
  35. rmPa674s2pfYo3KywkXQ1Fp3BC8GUgzPLSfJ8xXya9Lg1Wo8sHrDln0iRg5HXxGu
  36. uFNhRBvj2S0sIff0ZG/IatB9I6WXVOUYuQj6+A0CdULNj1vBqH9+7uWbLZ6lrD4b
  37. a44x/wIDAQABo0owSDAJBgNVHRMEAjAAMAsGA1UdDwQEAwIF4DAdBgNVHSUEFjAU
  38. BggrBgEFBQcDAgYIKwYBBQUHAwEwDwYDVR0RBAgwBocEfwAAATANBgkqhkiG9w0B
  39. AQsFAAOBgQCpN27uh/LjUVCaBK7Noko25iih/JSSoWzlvc8CaipvSPofNWyGx3Vu
  40. OdcSwNGYX/pp4ZoAzFij/Y5u0vKTVLkWXATeTMVmlPvhmpYjj9gPkCSY6j/SiKlY
  41. kGy0xr+0M5UQkMBcfIh9oAp9um1fZHVWAJAGP/ikZgkcUey0LmBn8w==
  42. -----END CERTIFICATE-----`, `-----BEGIN RSA PRIVATE KEY-----
  43. MIICWwIBAAKBgQDkGXXSm6Yun5o3Jlmx45rItcQ2pmnoDk4eZfl0rmPa674s2pfY
  44. o3KywkXQ1Fp3BC8GUgzPLSfJ8xXya9Lg1Wo8sHrDln0iRg5HXxGuuFNhRBvj2S0s
  45. Iff0ZG/IatB9I6WXVOUYuQj6+A0CdULNj1vBqH9+7uWbLZ6lrD4ba44x/wIDAQAB
  46. AoGAZbWwowvCq1GBq4vPPRI3h739Uz0bRl1ymf1woYXNguXRtCB4yyH+2BTmmrrF
  47. 6AIWkePuUEdbUaKyK5nGu3iOWM+/i6NP3kopQANtbAYJ2ray3kwvFlhqyn1bxX4n
  48. gl/Cbdw1If4zrDrB66y8mYDsjzK7n/gFaDNcY4GArjvOXKkCQQD9Lgv+WD73y4RP
  49. yS+cRarlEeLLWVsX/pg2oEBLM50jsdUnrLSW071MjBgP37oOXzqynF9SoDbP2Y5C
  50. x+aGux9LAkEA5qPlQPv0cv8Wc3qTI+LixZ/86PPHKWnOnwaHm3b9vQjZAkuVQg3n
  51. Wgg9YDmPM87t3UFH7ZbDihUreUxwr9ZjnQJAZ9Z95shMsxbOYmbSVxafu6m1Sc+R
  52. M+sghK7/D5jQpzYlhUspGf8n0YBX0hLhXUmjamQGGH5LXL4Owcb4/mM6twJAEVio
  53. SF/qva9jv+GrKVrKFXT374lOJFY53Qn/rvifEtWUhLCslCA5kzLlctRBafMZPrfH
  54. Mh5RrJP1BhVysDbenQJASGcc+DiF7rB6K++ZGyC11E2AP29DcZ0pgPESSV7npOGg
  55. +NqPRZNVCSZOiVmNuejZqmwKhZNGZnBFx1Y+ChAAgw==
  56. -----END RSA PRIVATE KEY-----`)
  57. client2CertData = newCertificateData(`-----BEGIN CERTIFICATE-----
  58. MIICBDCCAW2gAwIBAgIJAPgVBh+4xbGnMA0GCSqGSIb3DQEBCwUAMBsxGTAXBgNV
  59. BAMMEHdlYmhvb2tfdGVzdHNfY2EwIBcNMTcwNzI4MjMxNTI4WhgPMjI5MTA1MTMy
  60. MzE1MjhaMB8xHTAbBgNVBAMMFHdlYmhvb2tfdGVzdHNfY2xpZW50MIGfMA0GCSqG
  61. SIb3DQEBAQUAA4GNADCBiQKBgQDQQLzbrmHbtlxE7wViaoXFp5tQx7zzM2Ed7O1E
  62. gs3JUws5KkPbNrejLwixvLkzzU152M43UGsyKDn7HPyjXDogTZSW6C257XpYodk3
  63. S/gZS9oZtPss4UJuJioQk/M8X1ZjYP8kCTArOvVRJeNQL8GM7h5QQ6J5LUq+IdZb
  64. T0retQIDAQABo0owSDAJBgNVHRMEAjAAMAsGA1UdDwQEAwIF4DAdBgNVHSUEFjAU
  65. BggrBgEFBQcDAgYIKwYBBQUHAwEwDwYDVR0RBAgwBocEfwAAATANBgkqhkiG9w0B
  66. AQsFAAOBgQBdAxoU5YAmp0d+5b4qg/xOGC5rKcnksQEXYoGwFBWwaKvh9oUlGGxI
  67. A5Ykf2TEl24br4tLmicpdxUX4H4PbkdPxOjM9ghIKlmgHo8vBRC0iVIwYgQsw1W8
  68. ETY34Or+PJqaeslqx/t7kUKY5UIF9DLVolsIiAHveJNR2uBWiP0KiQ==
  69. -----END CERTIFICATE-----`, `-----BEGIN RSA PRIVATE KEY-----
  70. MIICXQIBAAKBgQDQQLzbrmHbtlxE7wViaoXFp5tQx7zzM2Ed7O1Egs3JUws5KkPb
  71. NrejLwixvLkzzU152M43UGsyKDn7HPyjXDogTZSW6C257XpYodk3S/gZS9oZtPss
  72. 4UJuJioQk/M8X1ZjYP8kCTArOvVRJeNQL8GM7h5QQ6J5LUq+IdZbT0retQIDAQAB
  73. AoGBAMFjTL4IKvG4X+jXub1RxFXvNkkGos2Jaec7TH5xpZ4OUv7L4+We41tTYxSC
  74. d83GGetLzPwK3vDd8DHkEiu1incket78rwmQ89LnQNyM0B5ejaTjW2zHcvKJ0Mtn
  75. nM32juQfq8St9JZVweS87k8RkLt9cOrg6219MRbFO+1Vn8WhAkEA+/rqHCspBdXr
  76. 7RL+H63k7RjqBllVEYlw1ukqTw1gp5IImmeOwgl3aRrJJfFV6gxxEqQ4CCb2vf9M
  77. yjrGEvP9KQJBANOTPcpskT/0dyipsAkvLFZTKjN+4fdfq37H3dVgMR6oQcMJwukd
  78. cEio1Hx+XzXuD0RHXighq7bUzel+IqzRuq0CQBJkzpIf1G7InuA/cq19VCi6mNq9
  79. yqftEH+fpab/ov6YemhLBvDDICRcADL02wCqx9ZEhpKRxZE5AbIBeFQJ24ECQG4f
  80. 9cmnOPNRC7TengIpy6ojH5QuNu/LnDghUBYAO5D5g0FBk3JDIG6xceha3rPzdX7U
  81. pu28mORRX9xpCyNpBwECQQCtDNZoehdPVuZA3Wocno31Rjmuy83ajgRRuEzqv0tj
  82. uC6Jo2eLcSV1sSdzTjaaWdM6XeYj6yHOAm8ZBIQs7m6V
  83. -----END RSA PRIVATE KEY-----`)
  84. )
  85. type certificateData struct {
  86. keyPEM []byte
  87. certificatePEM []byte
  88. certificate *tls.Certificate
  89. }
  90. func newCertificateData(certificatePEM string, keyPEM string) *certificateData {
  91. certificate, err := tls.X509KeyPair([]byte(certificatePEM), []byte(keyPEM))
  92. if err != nil {
  93. panic(fmt.Sprintf("Unable to initialize certificate: %v", err))
  94. }
  95. certs, err := x509.ParseCertificates(certificate.Certificate[0])
  96. if err != nil {
  97. panic(fmt.Sprintf("Unable to initialize certificate leaf: %v", err))
  98. }
  99. certificate.Leaf = certs[0]
  100. return &certificateData{
  101. keyPEM: []byte(keyPEM),
  102. certificatePEM: []byte(certificatePEM),
  103. certificate: &certificate,
  104. }
  105. }
  106. type fakeManager struct {
  107. cert atomic.Value // Always a *tls.Certificate
  108. healthy bool
  109. }
  110. func (f *fakeManager) SetCertificateSigningRequestClient(certificatesclient.CertificateSigningRequestInterface) error {
  111. return nil
  112. }
  113. func (f *fakeManager) ServerHealthy() bool { return f.healthy }
  114. func (f *fakeManager) Start() {}
  115. func (f *fakeManager) Stop() {}
  116. func (f *fakeManager) RotateCerts() (bool, error) { return false, nil }
  117. func (f *fakeManager) Current() *tls.Certificate {
  118. if val := f.cert.Load(); val != nil {
  119. return val.(*tls.Certificate)
  120. }
  121. return nil
  122. }
  123. func (f *fakeManager) setCurrent(cert *tls.Certificate) {
  124. f.cert.Store(cert)
  125. }
  126. func TestRotateShutsDownConnections(t *testing.T) {
  127. // This test fails if you comment out the t.closeAllConns() call in
  128. // transport.go and don't close connections on a rotate.
  129. stop := make(chan struct{})
  130. defer close(stop)
  131. m := new(fakeManager)
  132. m.setCurrent(client1CertData.certificate)
  133. // The last certificate we've seen.
  134. lastSeenLeafCert := new(atomic.Value) // Always *x509.Certificate
  135. lastSerialNumber := func() *big.Int {
  136. if cert := lastSeenLeafCert.Load(); cert != nil {
  137. return cert.(*x509.Certificate).SerialNumber
  138. }
  139. return big.NewInt(0)
  140. }
  141. h := func(w http.ResponseWriter, r *http.Request) {
  142. if r.TLS != nil && len(r.TLS.PeerCertificates) != 0 {
  143. // Record the last TLS certificate the client sent.
  144. lastSeenLeafCert.Store(r.TLS.PeerCertificates[0])
  145. }
  146. w.Write([]byte(`{}`))
  147. }
  148. s := httptest.NewUnstartedServer(http.HandlerFunc(h))
  149. s.TLS = &tls.Config{
  150. // Just request a cert, we don't need to verify it.
  151. ClientAuth: tls.RequestClientCert,
  152. }
  153. s.StartTLS()
  154. defer s.Close()
  155. c := &rest.Config{
  156. Host: s.URL,
  157. TLSClientConfig: rest.TLSClientConfig{
  158. // We don't care about the server's cert.
  159. Insecure: true,
  160. },
  161. ContentConfig: rest.ContentConfig{
  162. // This is a hack. We don't actually care about the serializer.
  163. NegotiatedSerializer: serializer.NegotiatedSerializerWrapper(runtime.SerializerInfo{}),
  164. },
  165. }
  166. // Check for a new cert every 10 milliseconds
  167. if _, err := updateTransport(stop, 10*time.Millisecond, c, m, 0); err != nil {
  168. t.Fatal(err)
  169. }
  170. client, err := rest.UnversionedRESTClientFor(c)
  171. if err != nil {
  172. t.Fatal(err)
  173. }
  174. if err := client.Get().Do().Error(); err != nil {
  175. t.Fatal(err)
  176. }
  177. firstCertSerial := lastSerialNumber()
  178. // Change the manager's certificate. This should cause the client to shut down
  179. // its connections to the server.
  180. m.setCurrent(client2CertData.certificate)
  181. for i := 0; i < 5; i++ {
  182. time.Sleep(time.Millisecond * 10)
  183. client.Get().Do()
  184. if firstCertSerial.Cmp(lastSerialNumber()) != 0 {
  185. // The certificate changed!
  186. return
  187. }
  188. }
  189. t.Errorf("certificate rotated but client never reconnected with new cert")
  190. }