github.com/Tyktechnologies/tyk@v2.9.5+incompatible/gateway/cert_go1.10_test.go (about) 1 // +build go1.10 2 3 package gateway 4 5 import ( 6 "crypto/tls" 7 "crypto/x509" 8 "crypto/x509/pkix" 9 "encoding/pem" 10 "errors" 11 "fmt" 12 13 // "net" 14 "net/http" 15 "net/http/httptest" 16 "strings" 17 "testing" 18 19 "github.com/TykTechnologies/tyk/certs" 20 "github.com/TykTechnologies/tyk/config" 21 "github.com/TykTechnologies/tyk/test" 22 ) 23 24 func uploadCertPublicKey(serverCert tls.Certificate) (string, error) { 25 x509Cert, _ := x509.ParseCertificate(serverCert.Certificate[0]) 26 pubDer, _ := x509.MarshalPKIXPublicKey(x509Cert.PublicKey) 27 pubPem := pem.EncodeToMemory(&pem.Block{Type: "PUBLIC KEY", Bytes: pubDer}) 28 pubID, _ := CertificateManager.Add(pubPem, "") 29 30 if pubID != certs.HexSHA256(pubDer) { 31 errStr := fmt.Sprintf("certmanager returned wrong pub key fingerprint: %s %s", certs.HexSHA256(pubDer), pubID) 32 return "", errors.New(errStr) 33 } 34 35 return pubID, nil 36 } 37 38 func TestPublicKeyPinning(t *testing.T) { 39 _, _, _, serverCert := genServerCertificate() 40 pubID, err := uploadCertPublicKey(serverCert) 41 if err != nil { 42 t.Error(err) 43 } 44 defer CertificateManager.Delete(pubID, "") 45 46 upstream := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 47 })) 48 upstream.TLS = &tls.Config{ 49 InsecureSkipVerify: true, 50 Certificates: []tls.Certificate{serverCert}, 51 } 52 53 upstream.StartTLS() 54 defer upstream.Close() 55 56 t.Run("Pub key match", func(t *testing.T) { 57 globalConf := config.Global() 58 // For host using pinning, it should ignore standard verification in all cases, e.g setting variable below does nothing 59 globalConf.ProxySSLInsecureSkipVerify = false 60 config.SetGlobal(globalConf) 61 defer ResetTestConfig() 62 63 ts := StartTest() 64 defer ts.Close() 65 66 BuildAndLoadAPI(func(spec *APISpec) { 67 spec.Proxy.ListenPath = "/" 68 spec.PinnedPublicKeys = map[string]string{"127.0.0.1": pubID} 69 spec.Proxy.TargetURL = upstream.URL 70 }) 71 72 ts.Run(t, test.TestCase{Code: 200}) 73 }) 74 75 t.Run("Pub key not match", func(t *testing.T) { 76 ts := StartTest() 77 defer ts.Close() 78 79 BuildAndLoadAPI(func(spec *APISpec) { 80 spec.Proxy.ListenPath = "/" 81 spec.PinnedPublicKeys = map[string]string{"127.0.0.1": "wrong"} 82 spec.Proxy.TargetURL = upstream.URL 83 }) 84 85 ts.Run(t, test.TestCase{Code: 500}) 86 }) 87 88 t.Run("Global setting", func(t *testing.T) { 89 globalConf := config.Global() 90 globalConf.Security.PinnedPublicKeys = map[string]string{"127.0.0.1": "wrong"} 91 config.SetGlobal(globalConf) 92 defer ResetTestConfig() 93 94 ts := StartTest() 95 defer ts.Close() 96 97 BuildAndLoadAPI(func(spec *APISpec) { 98 spec.Proxy.ListenPath = "/" 99 spec.Proxy.TargetURL = upstream.URL 100 }) 101 102 ts.Run(t, test.TestCase{Code: 500}) 103 }) 104 105 t.Run("Though proxy", func(t *testing.T) { 106 _, _, _, proxyCert := genServerCertificate() 107 proxy := initProxy("https", &tls.Config{ 108 Certificates: []tls.Certificate{proxyCert}, 109 }) 110 111 globalConf := config.Global() 112 globalConf.ProxySSLInsecureSkipVerify = true 113 config.SetGlobal(globalConf) 114 defer ResetTestConfig() 115 116 defer proxy.Stop() 117 118 ts := StartTest() 119 defer ts.Close() 120 121 BuildAndLoadAPI(func(spec *APISpec) { 122 spec.Proxy.ListenPath = "/" 123 spec.Proxy.TargetURL = upstream.URL 124 spec.Proxy.Transport.ProxyURL = proxy.URL 125 spec.PinnedPublicKeys = map[string]string{"*": "wrong"} 126 }) 127 128 ts.Run(t, test.TestCase{Code: 500}) 129 }) 130 131 t.Run("Enable Common Name check", func(t *testing.T) { 132 // start upstream server 133 _, _, _, serverCert := genCertificate(&x509.Certificate{ 134 EmailAddresses: []string{"test@test.com"}, 135 Subject: pkix.Name{CommonName: "localhost"}, 136 }) 137 serverPubID, err := uploadCertPublicKey(serverCert) 138 if err != nil { 139 t.Error(err) 140 } 141 defer CertificateManager.Delete(serverPubID, "") 142 143 upstream := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 144 })) 145 upstream.TLS = &tls.Config{ 146 InsecureSkipVerify: true, 147 Certificates: []tls.Certificate{serverCert}, 148 } 149 150 upstream.StartTLS() 151 defer upstream.Close() 152 153 // start proxy 154 _, _, _, proxyCert := genCertificate(&x509.Certificate{ 155 Subject: pkix.Name{CommonName: "local1.host"}, 156 }) 157 proxyPubID, err := uploadCertPublicKey(proxyCert) 158 if err != nil { 159 t.Error(err) 160 } 161 defer CertificateManager.Delete(proxyPubID, "") 162 163 proxy := initProxy("http", &tls.Config{ 164 Certificates: []tls.Certificate{proxyCert}, 165 }) 166 defer proxy.Stop() 167 168 globalConf := config.Global() 169 globalConf.SSLForceCommonNameCheck = true 170 globalConf.ProxySSLInsecureSkipVerify = true 171 config.SetGlobal(globalConf) 172 defer ResetTestConfig() 173 174 ts := StartTest() 175 defer ts.Close() 176 177 pubKeys := fmt.Sprintf("%s,%s", serverPubID, proxyPubID) 178 upstream.URL = strings.Replace(upstream.URL, "127.0.0.1", "localhost", 1) 179 proxy.URL = strings.Replace(proxy.URL, "127.0.0.1", "local1.host", 1) 180 181 BuildAndLoadAPI([]func(spec *APISpec){func(spec *APISpec) { 182 spec.Proxy.ListenPath = "/valid" 183 spec.Proxy.TargetURL = upstream.URL 184 spec.Proxy.Transport.ProxyURL = proxy.URL 185 spec.PinnedPublicKeys = map[string]string{"*": pubKeys} 186 }, 187 func(spec *APISpec) { 188 spec.Proxy.ListenPath = "/invalid" 189 spec.Proxy.TargetURL = upstream.URL 190 spec.Proxy.Transport.ProxyURL = proxy.URL 191 spec.PinnedPublicKeys = map[string]string{"*": "wrong"} 192 }}...) 193 194 ts.Run(t, []test.TestCase{ 195 {Code: 200, Path: "/valid"}, 196 {Code: 500, Path: "/invalid"}, 197 }...) 198 }) 199 } 200 201 func TestProxyTransport(t *testing.T) { 202 upstream := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 203 w.Write([]byte("test")) 204 })) 205 defer upstream.Close() 206 207 defer ResetTestConfig() 208 209 ts := StartTest() 210 defer ts.Close() 211 212 //matching ciphers 213 t.Run("Global: Cipher match", func(t *testing.T) { 214 globalConf := config.Global() 215 globalConf.ProxySSLInsecureSkipVerify = true 216 // force creating new transport on each reque 217 globalConf.MaxConnTime = -1 218 219 globalConf.ProxySSLCipherSuites = []string{"TLS_RSA_WITH_AES_128_CBC_SHA"} 220 config.SetGlobal(globalConf) 221 BuildAndLoadAPI(func(spec *APISpec) { 222 spec.Proxy.ListenPath = "/" 223 spec.Proxy.TargetURL = upstream.URL 224 }) 225 ts.Run(t, test.TestCase{Path: "/", Code: 200}) 226 }) 227 228 t.Run("Global: Cipher not match", func(t *testing.T) { 229 globalConf := config.Global() 230 globalConf.ProxySSLInsecureSkipVerify = true 231 // force creating new transport on each reque 232 globalConf.MaxConnTime = -1 233 234 globalConf.ProxySSLCipherSuites = []string{"TLS_RSA_WITH_RC4_128_SHA"} 235 config.SetGlobal(globalConf) 236 BuildAndLoadAPI(func(spec *APISpec) { 237 spec.Proxy.ListenPath = "/" 238 spec.Proxy.TargetURL = upstream.URL 239 }) 240 ts.Run(t, test.TestCase{Path: "/", Code: 500}) 241 }) 242 243 t.Run("API: Cipher override", func(t *testing.T) { 244 globalConf := config.Global() 245 globalConf.ProxySSLInsecureSkipVerify = true 246 // force creating new transport on each reque 247 globalConf.MaxConnTime = -1 248 249 globalConf.ProxySSLCipherSuites = []string{"TLS_RSA_WITH_RC4_128_SHA"} 250 config.SetGlobal(globalConf) 251 BuildAndLoadAPI(func(spec *APISpec) { 252 spec.Proxy.ListenPath = "/" 253 spec.Proxy.TargetURL = upstream.URL 254 spec.Proxy.Transport.SSLCipherSuites = []string{"TLS_RSA_WITH_AES_128_CBC_SHA"} 255 }) 256 257 ts.Run(t, test.TestCase{Path: "/", Code: 200}) 258 }) 259 260 t.Run("API: MinTLS not match", func(t *testing.T) { 261 globalConf := config.Global() 262 globalConf.ProxySSLInsecureSkipVerify = true 263 // force creating new transport on each reque 264 globalConf.MaxConnTime = -1 265 266 globalConf.ProxySSLMinVersion = 772 267 config.SetGlobal(globalConf) 268 BuildAndLoadAPI(func(spec *APISpec) { 269 spec.Proxy.ListenPath = "/" 270 spec.Proxy.TargetURL = upstream.URL 271 spec.Proxy.Transport.SSLCipherSuites = []string{"TLS_RSA_WITH_AES_128_CBC_SHA"} 272 }) 273 274 ts.Run(t, test.TestCase{Path: "/", Code: 500}) 275 }) 276 277 t.Run("API: Invalid proxy", func(t *testing.T) { 278 globalConf := config.Global() 279 globalConf.ProxySSLInsecureSkipVerify = true 280 // force creating new transport on each reque 281 globalConf.MaxConnTime = -1 282 283 globalConf.ProxySSLMinVersion = 771 284 config.SetGlobal(globalConf) 285 BuildAndLoadAPI(func(spec *APISpec) { 286 spec.Proxy.ListenPath = "/" 287 spec.Proxy.TargetURL = upstream.URL 288 spec.Proxy.Transport.SSLCipherSuites = []string{"TLS_RSA_WITH_AES_128_CBC_SHA"} 289 // Invalid proxy 290 spec.Proxy.Transport.ProxyURL = upstream.URL 291 }) 292 293 ts.Run(t, test.TestCase{Path: "/", Code: 500}) 294 }) 295 296 t.Run("API: Valid proxy", func(t *testing.T) { 297 globalConf := config.Global() 298 globalConf.ProxySSLInsecureSkipVerify = true 299 // force creating new transport on each reque 300 globalConf.MaxConnTime = -1 301 302 globalConf.ProxySSLMinVersion = 771 303 config.SetGlobal(globalConf) 304 305 _, _, _, proxyCert := genServerCertificate() 306 proxy := initProxy("https", &tls.Config{ 307 Certificates: []tls.Certificate{proxyCert}, 308 }) 309 defer proxy.Stop() 310 311 BuildAndLoadAPI(func(spec *APISpec) { 312 spec.Proxy.ListenPath = "/" 313 spec.Proxy.Transport.SSLCipherSuites = []string{"TLS_RSA_WITH_AES_128_CBC_SHA"} 314 spec.Proxy.Transport.ProxyURL = proxy.URL 315 }) 316 317 client := GetTLSClient(nil, nil) 318 client.Transport = &http.Transport{ 319 TLSNextProto: make(map[string]func(authority string, c *tls.Conn) http.RoundTripper), 320 } 321 ts.Run(t, test.TestCase{Path: "/", Code: 200, Client: client}) 322 }) 323 }