github.com/dbernstein1/tyk@v2.9.0-beta9-dl-apic+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  	"encoding/pem"
     9  	"net/http"
    10  	"net/http/httptest"
    11  	"testing"
    12  
    13  	"github.com/TykTechnologies/tyk/certs"
    14  	"github.com/TykTechnologies/tyk/config"
    15  	"github.com/TykTechnologies/tyk/test"
    16  )
    17  
    18  func TestPublicKeyPinning(t *testing.T) {
    19  	_, _, _, serverCert := genServerCertificate()
    20  	x509Cert, _ := x509.ParseCertificate(serverCert.Certificate[0])
    21  	pubDer, _ := x509.MarshalPKIXPublicKey(x509Cert.PublicKey)
    22  	pubPem := pem.EncodeToMemory(&pem.Block{Type: "PUBLIC KEY", Bytes: pubDer})
    23  	pubID, _ := CertificateManager.Add(pubPem, "")
    24  	defer CertificateManager.Delete(pubID)
    25  
    26  	if pubID != certs.HexSHA256(pubDer) {
    27  		t.Error("Certmanager returned wrong pub key fingerprint:", certs.HexSHA256(pubDer), pubID)
    28  	}
    29  
    30  	upstream := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    31  	}))
    32  	upstream.TLS = &tls.Config{
    33  		InsecureSkipVerify: true,
    34  		Certificates:       []tls.Certificate{serverCert},
    35  	}
    36  
    37  	upstream.StartTLS()
    38  	defer upstream.Close()
    39  
    40  	t.Run("Pub key match", func(t *testing.T) {
    41  		globalConf := config.Global()
    42  		// For host using pinning, it should ignore standard verification in all cases, e.g setting variable below does nothing
    43  		globalConf.ProxySSLInsecureSkipVerify = false
    44  		config.SetGlobal(globalConf)
    45  		defer ResetTestConfig()
    46  
    47  		ts := StartTest()
    48  		defer ts.Close()
    49  
    50  		BuildAndLoadAPI(func(spec *APISpec) {
    51  			spec.Proxy.ListenPath = "/"
    52  			spec.PinnedPublicKeys = map[string]string{"127.0.0.1": pubID}
    53  			spec.Proxy.TargetURL = upstream.URL
    54  		})
    55  
    56  		ts.Run(t, test.TestCase{Code: 200})
    57  	})
    58  
    59  	t.Run("Pub key not match", func(t *testing.T) {
    60  		ts := StartTest()
    61  		defer ts.Close()
    62  
    63  		BuildAndLoadAPI(func(spec *APISpec) {
    64  			spec.Proxy.ListenPath = "/"
    65  			spec.PinnedPublicKeys = map[string]string{"127.0.0.1": "wrong"}
    66  			spec.Proxy.TargetURL = upstream.URL
    67  		})
    68  
    69  		ts.Run(t, test.TestCase{Code: 500})
    70  	})
    71  
    72  	t.Run("Global setting", func(t *testing.T) {
    73  		globalConf := config.Global()
    74  		globalConf.Security.PinnedPublicKeys = map[string]string{"127.0.0.1": "wrong"}
    75  		config.SetGlobal(globalConf)
    76  		defer ResetTestConfig()
    77  
    78  		ts := StartTest()
    79  		defer ts.Close()
    80  
    81  		BuildAndLoadAPI(func(spec *APISpec) {
    82  			spec.Proxy.ListenPath = "/"
    83  			spec.Proxy.TargetURL = upstream.URL
    84  		})
    85  
    86  		ts.Run(t, test.TestCase{Code: 500})
    87  	})
    88  
    89  	t.Run("Though proxy", func(t *testing.T) {
    90  		_, _, _, proxyCert := genServerCertificate()
    91  		proxy := initProxy("https", &tls.Config{
    92  			Certificates: []tls.Certificate{proxyCert},
    93  		})
    94  
    95  		globalConf := config.Global()
    96  		globalConf.ProxySSLInsecureSkipVerify = true
    97  		config.SetGlobal(globalConf)
    98  		defer ResetTestConfig()
    99  
   100  		defer proxy.Stop()
   101  
   102  		ts := StartTest()
   103  		defer ts.Close()
   104  
   105  		BuildAndLoadAPI(func(spec *APISpec) {
   106  			spec.Proxy.ListenPath = "/"
   107  			spec.Proxy.TargetURL = upstream.URL
   108  			spec.Proxy.Transport.ProxyURL = proxy.URL
   109  			spec.PinnedPublicKeys = map[string]string{"*": "wrong"}
   110  		})
   111  
   112  		ts.Run(t, test.TestCase{Code: 500})
   113  	})
   114  }
   115  
   116  func TestProxyTransport(t *testing.T) {
   117  	upstream := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   118  		w.Write([]byte("test"))
   119  	}))
   120  	defer upstream.Close()
   121  
   122  	globalConf := config.Global()
   123  	globalConf.ProxySSLInsecureSkipVerify = true
   124  	// force creating new transport on each reque
   125  	globalConf.MaxConnTime = -1
   126  	config.SetGlobal(globalConf)
   127  	defer ResetTestConfig()
   128  
   129  	ts := StartTest()
   130  	defer ts.Close()
   131  
   132  	//matching ciphers
   133  	t.Run("Global: Cipher match", func(t *testing.T) {
   134  		globalConf.ProxySSLCipherSuites = []string{"TLS_RSA_WITH_AES_128_CBC_SHA"}
   135  		config.SetGlobal(globalConf)
   136  		BuildAndLoadAPI(func(spec *APISpec) {
   137  			spec.Proxy.ListenPath = "/"
   138  			spec.Proxy.TargetURL = upstream.URL
   139  		})
   140  		ts.Run(t, test.TestCase{Path: "/", Code: 200})
   141  	})
   142  
   143  	t.Run("Global: Cipher not match", func(t *testing.T) {
   144  		globalConf.ProxySSLCipherSuites = []string{"TLS_RSA_WITH_RC4_128_SHA"}
   145  		config.SetGlobal(globalConf)
   146  		BuildAndLoadAPI(func(spec *APISpec) {
   147  			spec.Proxy.ListenPath = "/"
   148  			spec.Proxy.TargetURL = upstream.URL
   149  		})
   150  		ts.Run(t, test.TestCase{Path: "/", Code: 500})
   151  	})
   152  
   153  	t.Run("API: Cipher override", func(t *testing.T) {
   154  		globalConf.ProxySSLCipherSuites = []string{"TLS_RSA_WITH_RC4_128_SHA"}
   155  		config.SetGlobal(globalConf)
   156  		BuildAndLoadAPI(func(spec *APISpec) {
   157  			spec.Proxy.ListenPath = "/"
   158  			spec.Proxy.TargetURL = upstream.URL
   159  			spec.Proxy.Transport.SSLCipherSuites = []string{"TLS_RSA_WITH_AES_128_CBC_SHA"}
   160  		})
   161  
   162  		ts.Run(t, test.TestCase{Path: "/", Code: 200})
   163  	})
   164  
   165  	t.Run("API: MinTLS not match", func(t *testing.T) {
   166  		globalConf.ProxySSLMinVersion = 772
   167  		config.SetGlobal(globalConf)
   168  		BuildAndLoadAPI(func(spec *APISpec) {
   169  			spec.Proxy.ListenPath = "/"
   170  			spec.Proxy.TargetURL = upstream.URL
   171  			spec.Proxy.Transport.SSLCipherSuites = []string{"TLS_RSA_WITH_AES_128_CBC_SHA"}
   172  		})
   173  
   174  		ts.Run(t, test.TestCase{Path: "/", Code: 500})
   175  	})
   176  
   177  	t.Run("API: Invalid proxy", func(t *testing.T) {
   178  		globalConf.ProxySSLMinVersion = 771
   179  		config.SetGlobal(globalConf)
   180  		BuildAndLoadAPI(func(spec *APISpec) {
   181  			spec.Proxy.ListenPath = "/"
   182  			spec.Proxy.TargetURL = upstream.URL
   183  			spec.Proxy.Transport.SSLCipherSuites = []string{"TLS_RSA_WITH_AES_128_CBC_SHA"}
   184  			// Invalid proxy
   185  			spec.Proxy.Transport.ProxyURL = upstream.URL
   186  		})
   187  
   188  		ts.Run(t, test.TestCase{Path: "/", Code: 500})
   189  	})
   190  
   191  	t.Run("API: Valid proxy", func(t *testing.T) {
   192  		globalConf.ProxySSLMinVersion = 771
   193  		config.SetGlobal(globalConf)
   194  
   195  		_, _, _, proxyCert := genServerCertificate()
   196  		proxy := initProxy("https", &tls.Config{
   197  			Certificates: []tls.Certificate{proxyCert},
   198  		})
   199  		defer proxy.Stop()
   200  
   201  		BuildAndLoadAPI(func(spec *APISpec) {
   202  			spec.Proxy.ListenPath = "/"
   203  			spec.Proxy.Transport.SSLCipherSuites = []string{"TLS_RSA_WITH_AES_128_CBC_SHA"}
   204  			spec.Proxy.Transport.ProxyURL = proxy.URL
   205  		})
   206  
   207  		client := getTLSClient(nil, nil)
   208  		client.Transport = &http.Transport{
   209  			TLSNextProto: make(map[string]func(authority string, c *tls.Conn) http.RoundTripper),
   210  		}
   211  		ts.Run(t, test.TestCase{Path: "/", Code: 200, Client: client})
   212  	})
   213  }