diff --git a/.gitignore b/.gitignore index 5f2be0079..2298e3d9b 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,7 @@ mender # Go test coverage output *coverage*.txt + +# IDE and editors +.idea +*.swp diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 86e874a35..282df6c5b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -29,6 +29,13 @@ test: - apt-get update && apt-get install -yyq liblzma-dev libssl-dev - make get-tools script: +# - cat /etc/ssl/openssl.cnf +# - sed -i -e 's/CipherString = DEFAULT@SECLEVEL=.*/CipherString = DEFAULT@SECLEVEL=-1/' /etc/ssl/openssl.cnf +# - cat /etc/ssl/openssl.cnf +# - pwd +# - find . -name server.crt +# - go mod vendor + - echo "127.0.0.1 www.dimi.fr" >> /etc/hosts - make extracheck - make coverage - make diff --git a/Makefile b/Makefile index da9f68658..94610c0f8 100644 --- a/Makefile +++ b/Makefile @@ -170,9 +170,13 @@ check: test extracheck test: $(GO) test $(BUILDV) $(PKGS) -extracheck: gofmt govet godeadcode govarcheck gocyclo +extracheck: gomod gofmt govet godeadcode govarcheck gocyclo echo "All extra-checks passed!" +gomod: + echo "-- checking if code is gofmt'ed" + $(GO) mod vendor + gofmt: echo "-- checking if code is gofmt'ed" if [ -n "$$($(GOFMT) -d $(PKGFILES))" ]; then \ diff --git a/client/client.go b/client/client.go index 05e6f4dcc..9c07e3f13 100644 --- a/client/client.go +++ b/client/client.go @@ -26,6 +26,7 @@ import ( "strings" "time" + openssl "github.com/Linutronix/golang-openssl" "github.com/pkg/errors" log "github.com/sirupsen/logrus" "golang.org/x/net/http2" @@ -280,9 +281,49 @@ func newHttpClient() *http.Client { return &http.Client{} } +func dialOpenSSL(conf Config, network string, addr string) (net.Conn, error) { + contextSSL, err := openssl.NewCtx() // probably should consider reusing the context, but we + // have to propagate it with every request + err = contextSSL.LoadVerifyLocations(conf.ServerCert, "") + if err != nil { + return nil, err + } + flags := openssl.DialFlags(0) + + if conf.NoVerify { + flags = openssl.InsecureSkipHostVerification + } + + conn, err := openssl.Dial("tcp", addr, contextSSL, flags) + if conn == nil || err != nil { + return nil, err + } + + conn.VerifyMode() + conn.PeerCertificate() + v := conn.VerifyResult() + if v != openssl.Ok { + if v == openssl.CertHasExpired { + return nil, errors.Errorf("certificate has expired, openssl verify rc: %d server cert file: %s", v, conf.ServerCert) + } + if v == openssl.DepthZeroSelfSignedCert { + return nil, errors.Errorf("depth zero self-signed certificate, openssl verify rc: %d server cert file: %s", v, conf.ServerCert) + } + if v == 0x42 { //X509_V_ERR_EE_KEY_TOO_SMALL + return nil, errors.Errorf("end entity key too short, openssl verify rc: %d server cert file: %s", v, conf.ServerCert) + } + if v == 0x14 { //X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY + return nil, errors.Errorf("certificate signed by unknown authority, openssl verify rc: %d server cert file: %s", v, conf.ServerCert) + } + return nil, errors.Errorf("not a valid certificate, openssl verify rc: %d server cert file: %s", v, conf.ServerCert) + } + return conn, err +} + func newHttpsClient(conf Config) (*http.Client, error) { client := newHttpClient() + //conf.ServerCert = "/go/src/github.com/mendersoftware/mender/client/" + conf.ServerCert trustedcerts := loadServerTrust(&conf) if conf.NoVerify { @@ -295,6 +336,9 @@ func newHttpsClient(conf Config) (*http.Client, error) { transport := http.Transport{ TLSClientConfig: &tlsc, Proxy: http.ProxyFromEnvironment, + DialTLS: func(network string, addr string) (net.Conn, error) { + return dialOpenSSL(conf, network, addr) + }, } client.Transport = &transport diff --git a/client/client_auth_test.go b/client/client_auth_test.go index 60477d9bf..1a73c6afd 100644 --- a/client/client_auth_test.go +++ b/client/client_auth_test.go @@ -19,7 +19,7 @@ import ( "fmt" "io/ioutil" "net/http" - "net/http/httptest" + "strings" "testing" "github.com/stretchr/testify/assert" @@ -88,13 +88,15 @@ func TestClientAuth(t *testing.T) { http.Header{}, } - ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + ts := startTestHTTPS(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { responder.headers = r.Header w.WriteHeader(responder.httpStatus) w.Header().Set("Content-Type", "application/json") fmt.Fprint(w, responder.data) - })) + }), + localhostCert, + localhostKey) defer ts.Close() ac, err := NewApiClient( @@ -122,8 +124,9 @@ func TestClientAuth(t *testing.T) { } func TestClientAuthExpiredCert(t *testing.T) { - ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - })) + ts := startTestHTTPS(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}), + localhostCertExpired, + localhostKeyExpired) defer ts.Close() ac, err := NewApiClient( @@ -145,8 +148,9 @@ func TestClientAuthExpiredCert(t *testing.T) { } func TestClientAuthUnknownAuthorityCert(t *testing.T) { - ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - })) + ts := startTestHTTPS(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}), + localhostCertUnknown, + localhostKeyUnknown) defer ts.Close() ac, err := NewApiClient( @@ -161,15 +165,70 @@ func TestClientAuthUnknownAuthorityCert(t *testing.T) { msger := &testAuthDataMessenger{ reqData: []byte("foobar"), } - rsp, err := client.Request(ac, ts.URL, msger) + rsp, err := client.Request(ac, strings.ReplaceAll(ts.URL, "127.0.0.1", "www.dimi.fr"), msger) assert.Error(t, err) assert.Contains(t, err.Error(), "certificate signed by unknown authority") + // see https://github.com/openssl/openssl/blob/OpenSSL_1_1_1-stable/crypto/x509/x509_vfy.c#L3268 + // for self-signed openssl always returns self-signed error; either + // X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT or X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN + // and never X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT or X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY + assert.Nil(t, rsp) +} + +//X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT +func TestClientAuthDepthZeroSelfSignedCert(t *testing.T) { + ts := startTestHTTPS(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}), + localhostCert, + localhostKey) + defer ts.Close() + + ac, err := NewApiClient( + Config{"server.zero.depth.self.signed.crt", true, false}, + ) + assert.NotNil(t, ac) + assert.NoError(t, err) + + client := NewAuth() + assert.NotNil(t, client) + + msger := &testAuthDataMessenger{ + reqData: []byte("foobar"), + } + rsp, err := client.Request(ac, ts.URL, msger) + assert.Error(t, err) + assert.Contains(t, err.Error(), "depth zero self-signed certificate") + assert.Nil(t, rsp) +} + +//X509_V_ERR_EE_KEY_TOO_SMALL +func TestClientAuthEndEntityKeyTooSmall(t *testing.T) { + ts := startTestHTTPS(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}), + localhostCertShortEEKey, + localhostKeyShortEEKey) + defer ts.Close() + + ac, err := NewApiClient( + Config{"server.crt", true, false}, + ) + assert.NotNil(t, ac) + assert.NoError(t, err) + + client := NewAuth() + assert.NotNil(t, client) + + msger := &testAuthDataMessenger{ + reqData: []byte("foobar"), + } + rsp, err := client.Request(ac, ts.URL, msger) + assert.Error(t, err) + assert.Contains(t, err.Error(), "end entity key too short") assert.Nil(t, rsp) } func TestClientAuthNoCert(t *testing.T) { - ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - })) + ts := startTestHTTPS(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}), + localhostCert, + localhostKey) defer ts.Close() ac, err := NewApiClient( diff --git a/client/client_inventory_test.go b/client/client_inventory_test.go index 3c4d5336f..4aa9d34ff 100644 --- a/client/client_inventory_test.go +++ b/client/client_inventory_test.go @@ -1,4 +1,4 @@ -// Copyright 2017 Northern.tech AS +// Copyright 2020 Northern.tech AS // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,7 +16,6 @@ package client import ( "io/ioutil" "net/http" - "net/http/httptest" "testing" "github.com/pkg/errors" @@ -35,12 +34,14 @@ func TestInventoryClient(t *testing.T) { } // Test server that always responds with 200 code, and specific payload - ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + ts := startTestHTTPS(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(responder.httpStatus) responder.recdata, _ = ioutil.ReadAll(r.Body) responder.path = r.URL.Path - })) + }), + localhostCert, + localhostKey) defer ts.Close() ac, err := NewApiClient( diff --git a/client/client_log_test.go b/client/client_log_test.go index be8d74f50..886f5f679 100644 --- a/client/client_log_test.go +++ b/client/client_log_test.go @@ -1,4 +1,4 @@ -// Copyright 2017 Northern.tech AS +// Copyright 2020 Northern.tech AS // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,7 +16,6 @@ package client import ( "io/ioutil" "net/http" - "net/http/httptest" "testing" "github.com/pkg/errors" @@ -35,12 +34,14 @@ func TestLogUploadClient(t *testing.T) { } // Test server that always responds with 200 code, and specific payload - ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + ts := startTestHTTPS(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(responder.httpStatus) responder.recdata, _ = ioutil.ReadAll(r.Body) responder.path = r.URL.Path - })) + }), + localhostCert, + localhostKey) defer ts.Close() ac, err := NewApiClient( diff --git a/client/client_status_test.go b/client/client_status_test.go index 253b701c4..34f8d76db 100644 --- a/client/client_status_test.go +++ b/client/client_status_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Northern.tech AS +// Copyright 2020 Northern.tech AS // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,7 +16,6 @@ package client import ( "io/ioutil" "net/http" - "net/http/httptest" "testing" "github.com/pkg/errors" @@ -35,12 +34,14 @@ func TestStatusClient(t *testing.T) { } // Test server that always responds with 200 code, and specific payload - ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + ts := startTestHTTPS(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(responder.httpStatus) responder.recdata, _ = ioutil.ReadAll(r.Body) responder.path = r.URL.Path - })) + }), + localhostCert, + localhostKey) defer ts.Close() ac, err := NewApiClient( diff --git a/client/client_test.go b/client/client_test.go index 0a0b6cdab..2644c3900 100644 --- a/client/client_test.go +++ b/client/client_test.go @@ -20,7 +20,6 @@ import ( "errors" "net" "net/http" - "net/http/httptest" "runtime" "strings" "testing" @@ -81,11 +80,13 @@ func TestApiClientRequest(t *testing.T) { http.Header{}, } - ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + ts := startTestHTTPS(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { responder.headers = r.Header w.WriteHeader(responder.httpStatus) w.Header().Set("Content-Type", "application/json") - })) + }), + localhostCert, + localhostKey) defer ts.Close() auth := false @@ -138,10 +139,12 @@ func TestClientConnectionTimeout(t *testing.T) { prevReadingTimeout := defaultClientReadingTimeout defaultClientReadingTimeout = 10 * time.Millisecond - ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + ts := startTestHTTPS(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // sleep so that client request will timeout time.Sleep(defaultClientReadingTimeout + defaultClientReadingTimeout) - })) + }), + localhostCert, + localhostKey) defer func() { ts.Close() @@ -360,11 +363,13 @@ func TestFailoverAPICall(t *testing.T) { http.Header{}, } - ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + ts := startTestHTTPS(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { responder.headers = r.Header w.WriteHeader(responder.httpStatus) w.Header().Set("Content-Type", "application/json") - })) + }), + localhostCert, + localhostKey) defer ts.Close() mulServerfunc := func() func() *MenderServer { diff --git a/client/client_update_test.go b/client/client_update_test.go index 1a7d4fdd2..8d9517d4f 100644 --- a/client/client_update_test.go +++ b/client/client_update_test.go @@ -20,7 +20,6 @@ import ( "io" "io/ioutil" "net/http" - "net/http/httptest" "strconv" "strings" "testing" @@ -174,12 +173,14 @@ func TestParseUpdateResponse(t *testing.T) { func Test_GetScheduledUpdate_errorParsingResponse_UpdateFailing(t *testing.T) { // Test server that always responds with 200 code, and specific payload - ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + ts := startTestHTTPS(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(204) w.Header().Set("Content-Type", "application/json") fmt.Fprint(w, "") - })) + }), + localhostCert, + localhostKey) defer ts.Close() ac, err := NewApiClient( @@ -199,12 +200,14 @@ func Test_GetScheduledUpdate_errorParsingResponse_UpdateFailing(t *testing.T) { func Test_GetScheduledUpdate_responseMissingParameters_UpdateFailing(t *testing.T) { // Test server that always responds with 200 code, and specific payload - ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + ts := startTestHTTPS(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(200) w.Header().Set("Content-Type", "application/json") fmt.Fprint(w, "") - })) + }), + localhostCert, + localhostKey) defer ts.Close() ac, err := NewApiClient( @@ -223,12 +226,14 @@ func Test_GetScheduledUpdate_responseMissingParameters_UpdateFailing(t *testing. func Test_GetScheduledUpdate_ParsingResponseOK_updateSuccess(t *testing.T) { // Test server that always responds with 200 code, and specific payload - ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + ts := startTestHTTPS(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(200) w.Header().Set("Content-Type", "application/json") fmt.Fprint(w, correctUpdateResponse) - })) + }), + localhostCert, + localhostKey) defer ts.Close() ac, err := NewApiClient( @@ -249,12 +254,14 @@ func Test_GetScheduledUpdate_ParsingResponseOK_updateSuccess(t *testing.T) { func Test_FetchUpdate_noContent_UpdateFailing(t *testing.T) { // Test server that always responds with 200 code, and specific payload - ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + ts := startTestHTTPS(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(200) w.Header().Set("Content-Type", "application/json") fmt.Fprint(w, "") - })) + }), + localhostCert, + localhostKey) defer ts.Close() ac, err := NewApiClient( @@ -272,12 +279,14 @@ func Test_FetchUpdate_noContent_UpdateFailing(t *testing.T) { func Test_FetchUpdate_invalidRequest_UpdateFailing(t *testing.T) { // Test server that always responds with 200 code, and specific payload - ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + ts := startTestHTTPS(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(200) w.Header().Set("Content-Type", "application/json") fmt.Fprint(w, "") - })) + }), + localhostCert, + localhostKey) defer ts.Close() ac, err := NewApiClient( @@ -295,12 +304,14 @@ func Test_FetchUpdate_invalidRequest_UpdateFailing(t *testing.T) { func Test_FetchUpdate_correctContent_UpdateFetched(t *testing.T) { // Test server that always responds with 200 code, and specific payload - ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + ts := startTestHTTPS(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(200) w.Header().Set("Content-Type", "application/json") fmt.Fprint(w, "some content to be fetched") - })) + }), + localhostCert, + localhostKey) defer ts.Close() ac, err := NewApiClient( @@ -431,7 +442,9 @@ func TestGetUpdateInfo(t *testing.T) { for name, test := range tests { // Test server that always responds with 200 code, and specific payload - ts := httptest.NewTLSServer(http.HandlerFunc(test.httpHandlerFunc)) + ts := startTestHTTPS(http.HandlerFunc(test.httpHandlerFunc), + localhostCert, + localhostKey) defer ts.Close() ac, err := NewApiClient( diff --git a/client/server.crt b/client/server.crt index 07457e03e..3ed40f83d 100644 --- a/client/server.crt +++ b/client/server.crt @@ -1,14 +1,94 @@ -----BEGIN CERTIFICATE----- -MIICEzCCAXygAwIBAgIQMIMChMLGrR+QvmQvpwAU6zANBgkqhkiG9w0BAQsFADAS +MIIRFzCCCP+gAwIBAgIQHfOtherbUt9X0dshGU89wjANBgkqhkiG9w0BAQsFADAS MRAwDgYDVQQKEwdBY21lIENvMCAXDTcwMDEwMTAwMDAwMFoYDzIwODQwMTI5MTYw -MDAwWjASMRAwDgYDVQQKEwdBY21lIENvMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB -iQKBgQDuLnQAI3mDgey3VBzWnB2L39JUU4txjeVE6myuDqkM/uGlfjb9SjY1bIw4 -iA5sBBZzHi3z0h1YV8QPuxEbi4nW91IJm2gsvvZhIrCHS3l6afab4pZBl2+XsDul -rKBxKKtD1rGxlG4LjncdabFn9gvLZad2bSysqz/qTAUStTvqJQIDAQABo2gwZjAO -BgNVHQ8BAf8EBAMCAqQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUw -AwEB/zAuBgNVHREEJzAlggtleGFtcGxlLmNvbYcEfwAAAYcQAAAAAAAAAAAAAAAA -AAAAATANBgkqhkiG9w0BAQsFAAOBgQCEcetwO59EWk7WiJsG4x8SY+UIAA+flUI9 -tyC4lNhbcF2Idq9greZwbYCqTTTr2XiRNSMLCOjKyI7ukPoPjo16ocHj+P3vZGfs -h1fIw3cSS2OolhloGw/XM6RWPWtPAlGykKLciQrBru5NAPvCMsb/I1DAceTiotQM -fblo6RBxUQ== +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 +JtoIM1SBFdXFCeo= -----END CERTIFICATE----- diff --git a/client/server.expired.crt b/client/server.expired.crt index 31112b398..1533f70dc 100644 --- a/client/server.expired.crt +++ b/client/server.expired.crt @@ -1,11 +1,51 @@ -----BEGIN CERTIFICATE----- -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 +4SfRRUwoG4uH7B1nLOFuI0NQNyXfuA568wc= -----END CERTIFICATE----- diff --git a/client/server.unknown-authority.crt b/client/server.unknown-authority.crt index 903d568f2..2c09b964a 100644 --- a/client/server.unknown-authority.crt +++ b/client/server.unknown-authority.crt @@ -1,14 +1,28 @@ -----BEGIN CERTIFICATE----- -MIICEjCCAXugAwIBAgIRAMQ8I/xATeFlYDeiX3H1XBkwDQYJKoZIhvcNAQELBQAw -EjEQMA4GA1UEChMHQWNtZSBDbzAeFw03MDAxMDEwMDAwMDBaFw03MDAxMDMwMDAw -MDBaMBIxEDAOBgNVBAoTB0FjbWUgQ28wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ -AoGBAJiCLkrvs3bels/qVWe5SojBygTrU7D1Qn/dZ7ZSJF1svUuvwDq8p6wHC1y5 -tX+KBjOjxtUjUdIQgfuCjAbw2j7hgrpEenieQpVTccb44aRa1ufobjKYhWiIZ+K6 -96udAaoSd1tt+TJpU2Ym2gWzWBMSpGAqKdgrmFfFMl/9mHKlAgMBAAGjaDBmMA4G -A1UdDwEB/wQEAwICpDATBgNVHSUEDDAKBggrBgEFBQcDATAPBgNVHRMBAf8EBTAD -AQH/MC4GA1UdEQQnMCWCC2V4YW1wbGUuY29thwR/AAABhxAAAAAAAAAAAAAAAAAA -AAABMA0GCSqGSIb3DQEBCwUAA4GBAH0gC0D1t1fZ+Nv5OWfve1n435EQ/eLOu0NA -AZ3LjRZjByytlBEvdO8F+xVeLhm/924B2G0VItotsg4888R7AZ43TceBFN4LvPDt -iRMfWmk3Z87fOiMADOFlxdCvA5ceA2o1VDnOblcIf8czSaVTXq9vrmCNhE8P0WU0 -L/r4D5nk +MIIEqzCCApOgAwIBAgIRAIvhKg5ZRO08VGQx8JdhT+UwDQYJKoZIhvcNAQELBQAw +GjEYMBYGA1UEAwwPRmFrZSBMRSBSb290IFgxMB4XDTE2MDUyMzIyMDc1OVoXDTM2 +MDUyMzIyMDc1OVowIjEgMB4GA1UEAwwXRmFrZSBMRSBJbnRlcm1lZGlhdGUgWDEw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDtWKySDn7rWZc5ggjz3ZB0 +8jO4xti3uzINfD5sQ7Lj7hzetUT+wQob+iXSZkhnvx+IvdbXF5/yt8aWPpUKnPym +oLxsYiI5gQBLxNDzIec0OIaflWqAr29m7J8+NNtApEN8nZFnf3bhehZW7AxmS1m0 +ZnSsdHw0Fw+bgixPg2MQ9k9oefFeqa+7Kqdlz5bbrUYV2volxhDFtnI4Mh8BiWCN +xDH1Hizq+GKCcHsinDZWurCqder/afJBnQs+SBSL6MVApHt+d35zjBD92fO2Je56 +dhMfzCgOKXeJ340WhW3TjD1zqLZXeaCyUNRnfOmWZV8nEhtHOFbUCU7r/KkjMZO9 +AgMBAAGjgeMwgeAwDgYDVR0PAQH/BAQDAgGGMBIGA1UdEwEB/wQIMAYBAf8CAQAw +HQYDVR0OBBYEFMDMA0a5WCDMXHJw8+EuyyCm9Wg6MHoGCCsGAQUFBwEBBG4wbDA0 +BggrBgEFBQcwAYYoaHR0cDovL29jc3Auc3RnLXJvb3QteDEubGV0c2VuY3J5cHQu +b3JnLzA0BggrBgEFBQcwAoYoaHR0cDovL2NlcnQuc3RnLXJvb3QteDEubGV0c2Vu +Y3J5cHQub3JnLzAfBgNVHSMEGDAWgBTBJnSkikSg5vogKNhcI5pFiBh54DANBgkq +hkiG9w0BAQsFAAOCAgEABYSu4Il+fI0MYU42OTmEj+1HqQ5DvyAeyCA6sGuZdwjF +UGeVOv3NnLyfofuUOjEbY5irFCDtnv+0ckukUZN9lz4Q2YjWGUpW4TTu3ieTsaC9 +AFvCSgNHJyWSVtWvB5XDxsqawl1KzHzzwr132bF2rtGtazSqVqK9E07sGHMCf+zp +DQVDVVGtqZPHwX3KqUtefE621b8RI6VCl4oD30Olf8pjuzG4JKBFRFclzLRjo/h7 +IkkfjZ8wDa7faOjVXx6n+eUQ29cIMCzr8/rNWHS9pYGGQKJiY2xmVC9h12H99Xyf +zWE9vb5zKP3MVG6neX1hSdo7PEAb9fqRhHkqVsqUvJlIRmvXvVKTwNCP3eCjRCCI +PTAvjV+4ni786iXwwFYNz8l3PmPLCyQXWGohnJ8iBm+5nk7O2ynaPVW0U2W+pt2w +SVuvdDM5zGv2f9ltNWUiYZHJ1mmO97jSY/6YfdOUH66iRtQtDkHBRdkNBsMbD+Em +2TgBldtHNSJBfB3pm9FblgOcJ0FSWcUDWJ7vO0+NTXlgrRofRT6pVywzxVo6dND0 +WzYlTWeUVsO40xJqhgUQRER9YLOLxJ0O6C8i0xFxAMKOtSdodMB3RIwt7RFQ0uyt +n5Z5MqkYhlMI3J1tPRTp1nEt9fyGspBOO05gi148Qasp+3N+svqKomoQglNoAxU= -----END CERTIFICATE----- + diff --git a/client/server.zero.depth.self.signed.crt b/client/server.zero.depth.self.signed.crt new file mode 100644 index 000000000..07457e03e --- /dev/null +++ b/client/server.zero.depth.self.signed.crt @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICEzCCAXygAwIBAgIQMIMChMLGrR+QvmQvpwAU6zANBgkqhkiG9w0BAQsFADAS +MRAwDgYDVQQKEwdBY21lIENvMCAXDTcwMDEwMTAwMDAwMFoYDzIwODQwMTI5MTYw +MDAwWjASMRAwDgYDVQQKEwdBY21lIENvMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB +iQKBgQDuLnQAI3mDgey3VBzWnB2L39JUU4txjeVE6myuDqkM/uGlfjb9SjY1bIw4 +iA5sBBZzHi3z0h1YV8QPuxEbi4nW91IJm2gsvvZhIrCHS3l6afab4pZBl2+XsDul +rKBxKKtD1rGxlG4LjncdabFn9gvLZad2bSysqz/qTAUStTvqJQIDAQABo2gwZjAO +BgNVHQ8BAf8EBAMCAqQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUw +AwEB/zAuBgNVHREEJzAlggtleGFtcGxlLmNvbYcEfwAAAYcQAAAAAAAAAAAAAAAA +AAAAATANBgkqhkiG9w0BAQsFAAOBgQCEcetwO59EWk7WiJsG4x8SY+UIAA+flUI9 +tyC4lNhbcF2Idq9greZwbYCqTTTr2XiRNSMLCOjKyI7ukPoPjo16ocHj+P3vZGfs +h1fIw3cSS2OolhloGw/XM6RWPWtPAlGykKLciQrBru5NAPvCMsb/I1DAceTiotQM +fblo6RBxUQ== +-----END CERTIFICATE----- diff --git a/client/tests_start_https.go b/client/tests_start_https.go new file mode 100644 index 000000000..c9bd89abb --- /dev/null +++ b/client/tests_start_https.go @@ -0,0 +1,568 @@ +// Copyright 2020 Northern.tech AS +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package client + +import ( + "crypto/tls" + "net/http" + "net/http/httptest" +) + +var localhostCertUnknown = []byte(`-----BEGIN CERTIFICATE----- +MIID0DCCArigAwIBAgIBATANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJGUjET +MBEGA1UECAwKU29tZS1TdGF0ZTEOMAwGA1UEBwwFUGFyaXMxDTALBgNVBAoMBERp +bWkxDTALBgNVBAsMBE5TQlUxEDAOBgNVBAMMB0RpbWkgQ0ExGzAZBgkqhkiG9w0B +CQEWDGRpbWlAZGltaS5mcjAeFw0xNDAxMjgyMDM2NTVaFw0yNDAxMjYyMDM2NTVa +MFsxCzAJBgNVBAYTAkZSMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJ +bnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxFDASBgNVBAMMC3d3dy5kaW1pLmZyMIIB +IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvpnaPKLIKdvx98KW68lz8pGa +RRcYersNGqPjpifMVjjE8LuCoXgPU0HePnNTUjpShBnynKCvrtWhN+haKbSp+QWX +SxiTrW99HBfAl1MDQyWcukoEb9Cw6INctVUN4iRvkn9T8E6q174RbcnwA/7yTc7p +1NCvw+6B/aAN9l1G2pQXgRdYC/+G6o1IZEHtWhqzE97nY5QKNuUVD0V09dc5CDYB +aKjqetwwv6DFk/GRdOSEd/6bW+20z0qSHpa3YNW6qSp+x5pyYmDrzRIR03os6Dau +ZkChSRyc/Whvurx6o85D6qpzywo8xwNaLZHxTQPgcIA5su9ZIytv9LH2E+lSwwID +AQABo3sweTAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVy +YXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQU+tugFtyN+cXe1wxUqeA7X+yS3bgw +HwYDVR0jBBgwFoAUhMwqkbBrGp87HxfvwgPnlGgVR64wDQYJKoZIhvcNAQEFBQAD +ggEBAIEEmqqhEzeXZ4CKhE5UM9vCKzkj5Iv9TFs/a9CcQuepzplt7YVmevBFNOc0 ++1ZyR4tXgi4+5MHGzhYCIVvHo4hKqYm+J+o5mwQInf1qoAHuO7CLD3WNa1sKcVUV +vepIxc/1aHZrG+dPeEHt0MdFfOw13YdUc2FH6AqEdcEL4aV5PXq2eYR8hR4zKbc1 +fBtuqUsvA8NWSIyzQ16fyGve+ANf6vXvUizyvwDrPRv/kfvLNa3ZPnLMMxU98Mvh +PXy3PkB8++6U4Y3vdk2Ni2WYYlIls8yqbM4327IKmkDc2TimS8u60CT47mKU7aDY +cbTV5RDkrlaYwm5yqlTIglvCv7o= +-----END CERTIFICATE-----`) + +var localhostKeyUnknown = []byte(`-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAvpnaPKLIKdvx98KW68lz8pGaRRcYersNGqPjpifMVjjE8LuC +oXgPU0HePnNTUjpShBnynKCvrtWhN+haKbSp+QWXSxiTrW99HBfAl1MDQyWcukoE +b9Cw6INctVUN4iRvkn9T8E6q174RbcnwA/7yTc7p1NCvw+6B/aAN9l1G2pQXgRdY +C/+G6o1IZEHtWhqzE97nY5QKNuUVD0V09dc5CDYBaKjqetwwv6DFk/GRdOSEd/6b +W+20z0qSHpa3YNW6qSp+x5pyYmDrzRIR03os6DauZkChSRyc/Whvurx6o85D6qpz +ywo8xwNaLZHxTQPgcIA5su9ZIytv9LH2E+lSwwIDAQABAoIBAFml8cD9a5pMqlW3 +f9btTQz1sRL4Fvp7CmHSXhvjsjeHwhHckEe0ObkWTRsgkTsm1XLu5W8IITnhn0+1 +iNr+78eB+rRGngdAXh8diOdkEy+8/Cee8tFI3jyutKdRlxMbwiKsouVviumoq3fx +OGQYwQ0Z2l/PvCwy/Y82ffq3ysC5gAJsbBYsCrg14bQo44ulrELe4SDWs5HCjKYb +EI2b8cOMucqZSOtxg9niLN/je2bo/I2HGSawibgcOdBms8k6TvsSrZMr3kJ5O6J+ +77LGwKH37brVgbVYvbq6nWPL0xLG7dUv+7LWEo5qQaPy6aXb/zbckqLqu6/EjOVe +ydG5JQECgYEA9kKfTZD/WEVAreA0dzfeJRu8vlnwoagL7cJaoDxqXos4mcr5mPDT +kbWgFkLFFH/AyUnPBlK6BcJp1XK67B13ETUa3i9Q5t1WuZEobiKKBLFm9DDQJt43 +uKZWJxBKFGSvFrYPtGZst719mZVcPct2CzPjEgN3Hlpt6fyw3eOrnoECgYEAxiOu +jwXCOmuGaB7+OW2tR0PGEzbvVlEGdkAJ6TC/HoKM1A8r2u4hLTEJJCrLLTfw++4I +ddHE2dLeR4Q7O58SfLphwgPmLDezN7WRLGr7Vyfuv7VmaHjGuC3Gv9agnhWDlA2Q +gBG9/R9oVfL0Dc7CgJgLeUtItCYC31bGT3yhV0MCgYEA4k3DG4L+RN4PXDpHvK9I +pA1jXAJHEifeHnaW1d3vWkbSkvJmgVf+9U5VeV+OwRHN1qzPZV4suRI6M/8lK8rA +Gr4UnM4aqK4K/qkY4G05LKrik9Ev2CgqSLQDRA7CJQ+Jn3Nb50qg6hFnFPafN+J7 +7juWln08wFYV4Atpdd+9XQECgYBxizkZFL+9IqkfOcONvWAzGo+Dq1N0L3J4iTIk +w56CKWXyj88d4qB4eUU3yJ4uB4S9miaW/eLEwKZIbWpUPFAn0db7i6h3ZmP5ZL8Q +qS3nQCb9DULmU2/tU641eRUKAmIoka1g9sndKAZuWo+o6fdkIb1RgObk9XNn8R4r +psv+aQKBgB+CIcExR30vycv5bnZN9EFlIXNKaeMJUrYCXcRQNvrnUIUBvAO8+jAe +CdLygS5RtgOLZib0IVErqWsP3EI1ACGuLts0vQ9GFLQGaN1SaMS40C9kvns1mlDu +LhIhYpJ8UsCVt5snWo2N+M+6ANh5tpWdQnEK6zILh4tRbuzaiHgb +-----END RSA PRIVATE KEY-----`) + +var localhostCertExpired = []byte(`-----BEGIN CERTIFICATE----- +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 +4SfRRUwoG4uH7B1nLOFuI0NQNyXfuA568wc= +-----END CERTIFICATE-----`) + +var localhostKeyExpired = []byte(`-----BEGIN RSA PRIVATE KEY----- +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 +-----END RSA PRIVATE KEY-----`) + +var localhostCert = []byte(`-----BEGIN CERTIFICATE----- +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 +JtoIM1SBFdXFCeo= +-----END CERTIFICATE-----`) + +var localhostKey = []byte(`-----BEGIN RSA PRIVATE KEY----- +MIIkJAIBAAKCCAACxeBDF4C6mg4yls/2Ie1mXB78fcXmaI1nOiTPQl1LlLriVXs8 +cPE0f3KeOwpaEQljdav7WoTZQ/qN+aFE5dON+McjKpTgYJ8C+35M3m5SRD2HE2aK +BKj/g7YnwgoXNawcyF0cwJWdHoeHuvYZCG/PULKUKcsyWckB03BM9NUOnqoeStxN +R7GDGP8lg7QQFfsDj84mmV6hOt/ZGszVgr6+7hdVN33UL75Tg7zfCJh5dnjdqw9x +vjofbtE2PxxsViAT5eOraEr216bEiDqhtENtu9NvVHSceQVQbUGzKnVnq1yUVO23 +y3eNF+KfpEj0VKF3+lEC531ZHp795CMWeZiWT+msbGTreKGeTwI7vU9lFRM1cbeM +BRycy+PYDFo1wupfW8zBXxnHgsT8dMMlv14Sq6dVDmNf0hQV1Z8tu9//vvk0e5iA +vuGEzny0AaIMEBH4DXZsKXvcBiZGbQ79KIGQI8luAPoHkwrTnS5UoN8u7ArDBTSi +mEo+m50h8KugSL9njFnDHXRnBBDkh6EBi4E84xVGD77dvnxdU3rVrdQcpYN/NdLA +aqIMaMs40NF2DJBmZjfJyylhKy/OMFiUt4zTuyl8Tu76HsqHQx7nxiQ3Zwbpq0tR +F8pKMfbwn/7q6Ci61ToF+K05mjAO36YssJpsLF1jqULPEGfYb9glQUp+HyemAqI4 +JAeWVlM0OZx7+IS4iSZoi2ky4Yh7spFEmm8VDCdK2ZRtgg8GW11ZKr5kJDuMS3a6 +NX21nf8GjgIIMS6mFFUCa4Dtc04ttmZ1tJAhPTwWdSXHlePM9E5bSeJnUBO8arnw +zOeq5vjVt6xAZseYKILgF9DRElJCptOLHFgNTNZtB4bvpnwaaoLUuk/RkCy7QcYf +0VMRZw07dP4hkbM4c5YoCegPEp2idJfC1xSR+Jt8bSac6AG9Abyb7eRxbzMPUD+A +nJ+Wwp90vIVqqmQSUd8Aj1/rtb5RPbanSc9LiRQsU/ph/xigiSFUdhhHG+fYfc15 +FZC8tCOg1+rmo+DGPB6hj/f6cm+CrZEJl8gLVWhuE175NjoS7ZANNEnEqIzGciEn +Vdu1giqVVwBVnzNii8LgKmEXwJYskOvRdlkZoCCB3puzgKQsuZFI40WclLS4Sb7e +rLd5W02R9fEi5QgxzWM1csPxEW1RzGOFDfjgO0ACO3Kf2gzPz0WKfSyAG1EeQ+Zz +j1Ea/Ei7NtbOFuJ6ZPraOA3SMgATJPeCCjVFG7l55bwbzrFDlvlWVCDJaQofrnFu ++TEWKlS3lpiKXg/e7FsDDYmIQX9/ylHLrTnoposPfi+EiLjIWxawK2sk8xKgv/JS +OUV/+RA+Hna8uon9Q1SeE1H8zbAh+d2fw27VvWMkzp+LoZz3wjdEU3YNM2Fqom6Y +R+sroADSctYA0Ews0DGYEJhZtMWgQGtuSKKu3PHG0/dfqAQt4/R6DaiZkEZCclGW +ZqFwuZA8M5My5ZQBzk9OteOmFxesuSc82twkTq2ZqWyXZ187I1iATyeN2JN0u71j +QgIOje1F38SmuRN6i9D+qeVuQF6b1GeRIF+iNFDPzmW9/9VJFduNPlN41i9eDs5j +8T6QgGKa+2t+lATZBdT2Uw34oS3JK8XOLt/acHN3lgE2K89VhqIvbq5ocOk7DvaJ +6cg8b8bcgOAWd8qRUohJisUPcrCDz26vA5fTT0YwIXatiBywSo3jiN8H9XxUllPF +WJNwwufEZ5qNh1866fWvu6WuTbJuNVI04LdNYf5CpZ6EMK07ToQPHPHfWAEUV6/2 +MPoQxy1qx464TqyRvuESC4i3+WmAkAeEu8glJLMZtg1aI+NAHAF0QGt6EXqiHsIy +H5MyLHlOe2eHNJBogyI5gGj8uJXTa/w++sNmHztsjez8N07+nqUcjMI9jdmqOY1L +HXKpkouIiFlwWxRTDkJg73tblJLcPH4rwrfb023ei2UOswkUj/qwtNfgMQLaPXFQ +Ab6gSfeyc1BmSHSOu/5ac3SXIznOGLrFpCBxqzxJMr/gkKAEk+f8ND8thotcJ8zU +mqVY8UVivfn7gTtfTtPTYQ3nieCjRLlqEuE7HlVNqEkIRRVcbapBtN0ajUexay4R +zvRtysHH8cbomWeQiXwelmVJq7iAqXr0bFIRiuv7/NpxU3kHABGVFfcradMmYmBS +gn/jyiOkdCIKIymzG7TqFsROcVvybWJldUHmpwdc0TzU9n/7vTyp45nwy0sG7vTj +5nyCtbLxvazGlZRrokFCRb9Vx+fUeZI2BTl+xh8w1IRWHOzglvcTrEO4vFgrMtkz +V+JqorGaWTokCZLSs9qINsLG7Dh9XMTb5yYg0oxoxGQAcnQrl9yVS81qvj21ran7 +huj9O/e7kdBLgWRUlHLzmMrxubAnVtcZnhbCAh71sPpStMaA/g0IyHCIVXvNg28+ +DQwzHlC8XpJ5WlfvbKchyQE9uS1wrnLZCJS0FCHkbIf+kT8ZcDUUQ3TNo7xpfgmX +bEIie9rvUD8ofw75DzMDU6VZ3dmnYL6vEJ1N0P5ZUc32w95KK7vHPDXwrxfo+Tat +mOEbk/m0xj3uxicJGTSXrs02n7aIKd8n7FLI9nY2ssBrYcOJ2dxD878yNQabW30Y +AKmSar7bvIZLWRdZgYpMIdrnteIAf0LgjHUN3IxDLSKetCgU4Ao89II4E47iUMX4 +j1kQCGrlbOp+slhMiM8sVXXoMiJFOX0wKDeaJC2DUYxWjaQKbMgUWepS/wIDAQAB +AoIIAAI/dHAO8mzSi+XYudb2Y+ORlBDsyGvin5Zp3QMi8kxd0i2+S/uQNwhutHSu +udKPcwPslTFajM0vvUIwddpLUPcLECtiznMiAGVDiHw56EbKSPJh+MKzymfv1s9e +Dh4IhXCDwG+Zcu9+mzGdjvh2DWWLLmjLhIxZmoffZm8MHlcOqiuKVhJTpwP2VIeN +v382wlh90AkcVUjwWBxADIKczZIrokCTjm5fEbPT3F0VM71rG8nebNOw+J8Yj4Kh +IKJ2IuTefHQsRHDcGrXBFX6Wif6/v0PFvA5IUNWE7DiYl7olgRRB0L8oss5u6Wiu +nfFrVcXT5q4rCEMhfpOkyAjlI5veRjhfWmREUwfpVo8lBOKVdg/iEn/weORmqFow +kUR5sNMCsPak6FoCmTtqT/QesN0Dx888rbQ0sdGNbc9+OLSylIRGGTdtBZZKaW7m +z/1lXZuvFivSaTTQy2BV8kuo9Xbqe9Sv+AAB5EntZmx2SNZZxNOZObUBLVaZgYTM +++QgdQE1FmMEUqNb+XG4vP1qoKbCEzHLe9d4HortLGth0cwzJGkQMbuH9buHjA6P +wO0ofDp2bI0qI25Auy0zpetQ7FmLpLK/rhyWr2l9MOWEi0FaRJFSKekgFv2UiXFA +0j6NWs8yISpMD+jdJE46YRRjSZudT0uGH8GJtBURfa+dwQyCpvp9shE+q+PkMOjq +Nv+MU9LgY4FmWi5EBAb6l6Z8ZsYyJvwXa6pmP1XQ5NhuvQ6jDJ7LYgDLcg+zd9RR +dDY94GoDm3ItwcM7sMl/zolmiVxYrogqCSlFSfiQp6B7QYysroMUJY2eHcM+H8Po +dDt01iJz3Lxasg16A7NCV8SygnKtsjmKW4mUdZBYfZyDOEdSz+AxDrImV2eJGYH0 +cjq2SQnfMX9doH/vgFf8mjX5cxRt62WvehjCPv6AFOx2qbSHB2ZHkGLrFLf7J5ZT +aPgyDpOHSPbEQ2bp2tEy7Qmp3OCHzBGvNg8Q417oK1uzrDSg2451VQbuQ3mlsigm +QKcdfA5XGCGyerzM3baaizOylhkR8GkjTN9LZUKI0DjUBWTlmdEZHeUsRcJbNbgA +YiYGu3oMgDqGQFUn6tVP2crgXJRYaWG+GowmIXCcMblbe8fWCLZIGfGbI9S9/iDv +tb2q2ry8mcrvMQYQMYWY4agvzmu/vEDS/jW1ZqNjjCUbGeLzwgt90agmKwJsN22E +pBdHF+tORsh1nkah/8uFMRt6uPo/4lh9ssL8CFkZXyDra/S6MNnD6PKkEXW9dRWq +gBfS7pyxD4pnA/Gv3vKyCSLKV2JQ9/PkQBL5XooUxUykteOrJJOpZn/fK4b1WYRx +36FYupnTZhoK4XDFMR4p1s43eHai9xEcKITViAlacw4f2yEqixotL9WZKU1D/rRh +GVg2HmN83x4XuRY8Y7xXRuWe8qDMwl9W8n+P5D2y3p/MXVd7qqMCQwouWgmKsIj5 +Mp4CeLF691ClNJx763ipiPg/xvj1PzYCRGXRZCkiWm+mAUf/tyTTZpUrY/dbzheg +rOJq0/NYa2y3rw4QdBy1U8F65gvHXfmAJpbqFJfFDQ+d/HUflyFJ+oWUdwZK4pc/ +EFVwKRq7knCjVQjfEn3HSXB7hUynpE8Uo8Bkwtx7mMtXOFf2mcNaSaZ9MUnOkRIh +przdbNt97ChO0hjrAAu6TrZerxiWjW4eGiJDyC76XpzqfpsWl4mhyDV9/HI74h8/ +m8fFdVOeXLDUmH6BPl5Wamx1PYJnI1yiiFeKDzY/1bY111ap/3Eu5pDafBeZu0+g +pODwq9IUhgzCZvwvU5mEYq7gWkeEee5kB6NrC190e4awJNia2/ikycq1hPxy7wys +y8e+6JuuBFuUJuE8sOkGZYw7RldwJ3py3M7U/R03roOkAIBhUHcOaxD2qeLL/zth +HsAR/D4RhvNfYzx6atdJHQV4/3zZhC741G6V4qW4Vyki8XUpFtF0oEs3lfaz0052 +jpnmiSYqeXcW470yF2qcAmC7MX1bCM+Q1cduHERbikiovu3Fk2OTWdleNjsiRIQg +snSKlFxgj/BKKP6obt8A2rgHRfvgJvTJ9jJPzjoY7/03N7Uc1xbyby3quBes/N6O +v/uim4PHJThGXQYsFr47luhvJvlby6U/oi5lEHZlqarU5X7aJAnOiSoSl63etyWA +Bqu14wW5lpEnidUVCFWEFq1Gs74G2fMuIm2s0T9SVs1wIR39VfLtsrZHo4LMqaDD +PHIBgkhPv67FrQXC3s7KS+zqDkrKq3LyvCsikvQZuNyJYKuHoE36pOIf+MBD33Ua +T09VxelRH05bEou8DHywDSdYcpTU09txjPk1KfauHhXFXBwnNeQUqQmV/09ZqQmW +5q0Ep4G68FdPUDY1ICsnWUyz9UvvBH15IXS2C1AsHzCdEjU4w042VkhkGDPDHj1t +OlAsDwqiNFgx9e1rzP2Yeo6VMhE8FNdciu1u5Bkghki87gx8v2r7HWi9V4xx1yDz +O+HB+a2vw/60qjwBOIi321MIM3AncZ8w4ymz6/lHzIdxkpnAXctckeorRzjuE0U0 +pFm7856XsuyKG8koE1uzKCy14revCw0ebNiBRBeuEuPe6ms9M52d9lOLiVvr5+Ai +mPni0Z2rqIji5Jj7CtBBKKKW8q5xKHVgV21aEkfRn5oZ/EBnsvyixSGoGVN4wxmD +nT9Rh9KCAe2lhXnnSczQdudAKUez6oSlsj3y+9iXeFf1uUqpAoIEABgN9jvMlDpZ +PS9X05Hzm3dtXUfvla6OqsBP9H4ZhBDAjJdo481/52ZshqaGxHS6aJGTlgEd9hnh +UjKZ+AJ1br8fB46U8y2H9iYZlJTExVGioVO51/p7lqXiFdQarKhuphwt1KQdpYZN +w0G5CcJD1FGTq+fK/CBp7rZxTKYKquHqD6JDtfDJ7CEA4Vf/SHIf7llMUCqdpUl4 +zsLqryixqol4C00A6GZU6GUTcX5YUv1A2eyJimccKBrMkYm5nkBN/jgpy6AeNT36 +Am3n4geIXcq4zwRrmiuT8+TxAxEjkqzuyyh/GnfsNIkaUl/9kL570l/Nv2kJpnBh +odVJIttHKhj+mmoUe64t7e3QJluJqMG8L/iwvifSHDpgJ3CYCZ8rpo1Q/7Q+HXTO +AQaURH9B0nWSlhxbKZNYeTS2s/X/tnnQNzU4oVzlt/yf7o87mxjD+8YeXQMgIgHY +W7zVlBdsoPPl2owPEZkweRyXtZUDd0+RKew65/IdckpVpTwqAe/eomkDZZlIgIBw +HnoZrC6j8DtoRUiHd68rgjkloExzefn5QvIeO5KB0ko5aMSypJHtOrwocVC32qHL +RUW7aoBQC90sfD7JIZtbweTIx19wEuBhl4cLD9JyU6uSyeBFU2WBRpBJ1XR/1OOf +r0JNGv5I9SLOjt+HjwBaGmjVMaXyHUZz0YuHdNWM3OcIjN/NMk5SZV0TE0vuGfAH +V5UZAKtK+I/OHPSTURCtNRkQxYDJaKKTxtpzS3o3ppECG+RVDZjUZReErNojwpd/ +i0k+g7MDFFqK7BzKiZHna/sniw3dIebe79LOlN7HsxKjq7kpkwDAcepBedQUuBc5 +h9jhhRWwwNwv2oudpPUGhRohYMBidCMCcQhhMo88MNCNDf0zNkDb6SaDmy1QUwIx +E6D5jV+m2Epm7ZxWQoO+/qy1K6c5JX0F0vTA8H18DYf1Ofo3K4xHs2u15qKE8Mxu +JcAEpzmVZvAUWwsnH2LnWthqONctR1DF84QzAttZoCXrHm6DvrdYguRvDBwSVEJv +3k6Dc8vNVGFJWsVMHOeOT7xjKkp+JNHT+DyxTdbryD917xVUlvlo4hsWQbSUXAmm +H44LAU3evLXgLKTsrLX0dPBCJ/Y6aJdXgixAgJyVfmcFkdpSwD05k2n+hnfQvERG +gjq5ICx4AS7LE2IANFeAh5n7YiDFgitTMQOgWy+km8zJyfZdieW1cdKpT/YoMIBT +iKPj4WsawJipHw+oRvuGhQk9pb/uxDvLtC2pP5O1GnjdMXTIxYEJk0STKZ6HnYC+ +LLPDq+wlLSpDee7n53McZP+p07VrtIkTyjWFrjEwiiyct05ejoVdAzGjB2VV80Vl +ItR4ucVArh0CggQAHYLX0BNc38URCEM6GTUl+OXxzJKW3mONEENQOen+ORBY/cvM +QnuPtQTcnwTkFf0t175orMrbic9aY4kmM1LzpfkKQ+IMIfRcf9d0Cb5fDxRztjEB +scIhwpiul8AMkT45LcVtOkNnXkpXFodiYxQaltoPwXXqUaKscPD/OwtZ1FiOvLS1 +pKTOnHeEXZ0vE3i1ai94zTASqCr7QNfHSE8xzLF1pfdeTGDXlc8u4KKG+1K/z/Q8 +oy4Kse8H2jer+T1CLEjjOwaB2W4QkrIlCrqDQVdSuoY60XSuAR1ElctuS7DoaBKg +l19L54FVotXbu3P3drNkpudyx7XM7TxGeNTWxG26b7MHvGsl1zS3bZ/DuYDJYarf +GLkYtGx1SKrosChYk+Vnkx/BCcHD1qt8q/jqV8UVTd6pbMorYUe/+qKWWVm4snij +S4X2/VLDPDlQV1V7TBR/zRY/cv8qeVxdY3tKbqH9aHePuSbIsbBXzkCJVKNyT0xj +AG6aqDff27k6BuVtEL4FZItrDDHO5xMWRCUr7Mes1NVGt9SWmQcx541Z+19/PRJb +IzmnXrxNVpfV7864lO58g41A+Ftazx3yOu+/a+0FlIXTOODJwNHA1VDGuIahA0Wd +hHu6BXFcwtN+MmkGAkKn0KuRSGYuwsvv9x+2CvtvEci+vP6xk10h0892+IOWRx2V ++SpUubmrjAcAG5Krfqk7RtXQjs7z+GTklMMzDOEPsVacXO6UpJ7jiVObbXYnqdDe +WWIa0DY8SEM7jVHjlP1NuO7Fe13rukspGea6rHKPRRf/BAt46Pxve9OzAswbUEfO +PQbwngP4N0YNZRh3/ytPLnQKgdPhEepq4xJaMjX6bN06c1a5pkiBClVYkAevS5FI +oQbl/ymxvHrL/Gt6M2Tz4XvtGVN8/MokZdPn9LddoxCRCiHA2ktvJQNkEpW+kcIk +Qy50ICjpTXy0wZy/d04CZJkOm2cEnS61nSLR69Mr1WBN46xWftMNVmwVkHkv4KB0 +41uoBuAl3+yt4IqjsGwix+DPYqdT0lrt3Y7hni6H4QbRAreyuicLdTDV2qwcdVbU +f5F1wZluYkk/6olmprzkXasQ9ZmLbDdqZboGkLJ3WAZD3iqqq+hoZMs5h0KCCOLR +nzquoRwEXmv+/9gWRTPSyBdN3TdCAOmtKBXjf4MWt7pHe5Hy5wCRJQMqY+/I5jMd +jR3c3TSNLIFkNiOJbagxLrNEipzCsqFuydtBTkUoNoOP5ZNFe6lKypLowWz4HFB5 +At4HVWln9yoVax8gKHwO7ZdtCOpAgj42W4HmBlvVN6IXisWbOUtfXt38sz+uPQrI +231WrJ1GqzEsxi1BDKM9UpvwBiY+sflwsDWqywKCBAALLbHYaGIaG46Lic0Qbp05 +CuHmpDhzPmmrpXyBfWoaPuEXG++BeIcY2iZZDRgPBvHBdUyoiDvuGwAP8+2Fdv1Y +ZBsm76Fy71Q8sHaUDD2GioVeW2c7SGPiAwcR4rOKMqGPRt0ix4Q8vbaXvF4EoXDx +2CZzOamhhpkgv9ZW824mPpe1WLIcjDnnvHj8Y+5O2vfxF73JkClX04SCoH1189rE +t7zItDtMEvlMv5RmmrU2bATaH7Dp6fPZQGgCEPix+YzCnOm8J02m16B5YuFvjrfH +lcreywKCbedR5Y7/UADBzNcsoqSyRlrDvC+73CJ/4xsI2pyxO4LVhwmmDK7eKFwv +8WHhGlO/xihj8+9fasG6BrJkZ/52kvX7SuQJNx6Bkc98rL+oC5W0ymc/n3eVjAk6 +Cj0oQFU53Eu3a5CGKaerRE/js8WJXlf6VniOp6yT/b/regDPiwdCxEEdqEOB/0Ft +FsxRek87WYNu/jGsZkfz+gn5dgaERZrvYI3BP+RWjKf9FU8JxN+y0GfZZkTWB+mE +MhjAc/Pyu81wsUOlQ6TTvjqWOeaFVz9arwM5JavFBPHerwy57jb0KXqvxUDhEFHz +HtE+fEnZ4PJiV8wPVg3vqGq6nzFjIy4u9bBLQOxYp5MbSrSfxygv/+16akq5ET6a +RlOvHVgfWcAcJ7dC3xkrvHcM2I47D5M46ohNGRbfvvrMHilBiA0VttPEvjHJaLXK +XoamQi/SCCw80cZ26yJtKy+mJR5WVbZafRhpK/19oHa6TzXkyemMbgFUsHCTqEK1 +MQo49wanf1x3AxFkB/fRSpk45jfYsAVQDC+phOCD4OsPag4ruNU0NdAjweoPAm0d +5j8x0rjuBXGliw1jWl2OR3wv4LuWROqKgIKXwEzeJ1RaSZ67mDB7PENa8533bZnm +OZ8CoDOY9hF0QV1gAPai+ynmBCO+rP+8xwGCflEGh+uhio77x7v/xNBWQ9NSt1N3 +Dn6g2DWFyO421GZF2QzjRJq+PNZ/CU+bT4B860yd98wcTF7cTMhLd6Ff60bM10b3 +TxeXyJ9GHKSBb7Qfmi+SM2eRDPSXhEsy8qOAzia7ETrCS72NJcT/1uujHwokHfak +ruEQY8x/YnNVk+juTIZ+jnQ4DGG4YuCzD6uQQhSEX1VaVKY42BAlyn6Ku61v/PTP +wh/n0yB/6YMa0+/uOtsbNzX38XVu1phwuvXYP+/tiDy1IWm/gz3G5QsC3svK8ku+ +phmBNTqHeSQp/zQf1d3ry+aXsaeSBP+gW2q4UvU12jVOEPWubmeLhNVRVQV4YG50 +zZbEp5CvtepZxZpVHRBxA3ldFhq1UVFlGg81pEunPmpVjuXI+gBrp2xgQRpTyJMh +AoIEABo4+39e1TXZLCtFYUio21bxLAx1bS2rE9uRlKYBb+5QwmKyRowEs0tMSKXc +eLe5QpTkEqsHjlBEObMcWR9d5DZktmRfZhx9v/uw/ODzkhAaQj9wCGtlbw41EV6y +PfiJa9FqDoapAh7cu8m+/wO/B2ln1nw3RMDJZaTt4D0c9vMixaKUiJsF/rk10h5E +32HT7o+uIw9gWhOoLZ4Onnt4M24JedrBlb8UhjwN3z+n631CqEImagMtlD9LgJS8 +x0kuz6/+DDuUqqkDjiJrvVJtLNhQuagYQgeAQGWpFhpsq1MCnWBsvNoEybOqTufk +U92bTBbjjNpp6qnet3tOBei0ZyofvnwmfwdDxloV86+rOQWKlGb+qEKVpogbn5O0 +mhJ9p0eznncyzhrXXCdSNfOxuLnI3AdXhQCwHB/S25ngAuzeNqoPXDptjWzHr8fB +vcv8nxSZWn5n+HU8mwc/tZQCJ79qnXvIUaNZ/Rc29K7G1cCpg5dG7umhXjd/fqEF +U7RxBJrN3ojbAYHSeGEHqs9eoEtDmiV8ZdxPQIo1xHhWN9CPqMYhm24PetNJSwdY +37a433cm+ukCCOsmceh8WZNZGaTS9hRlXay6wUtelpR1tD6fEk+P+kmQj1jqxFwy +BX7Rp482n1tiODQ25/IbuNzEBsR3athIooPZZPzm0nodbT+h3VTPy0WeAa8Odop0 +ZfoaN9zSj2N/9lQPPOZI8Hvnf2NAUOtpZIOHU/l7Xf/WlNONG+1fNVQDQoQkzSgA +5dfLHghzlC5xrHTUnfPpeVoUlWdKXFgu3GFBuGx+cql7ESO5LcQGKhI8Km6eZF7p +Flnwhh/s4e0LG5MFLIb434Vp90+Kez1kzt1SAKDq6A7Ai3NgALmLHRhIwvIaoF40 +VzGyZuFoIPUJY0MP1o3hKLp6sy/WB5Qv0lFIcM8IHHitLKz+9lkaQ5KWooU5FSXP +W+Z2XAOtA59UCZC413a73JEGMbX07IwriMp3hlwnOUDDxd2ccZiNu4+TEBkb70us +SUyupIjNbZJiBqVIvci7F4W5wm0GN6MSpYJerKeQrjOx8zTdnmP9hdDc9d/TcCxR +nkPPV7FtQxagPO+fQi4kh5xg0hidHELRPlkZXJJobuqxUisIQ/eVZGKyiB2Mga1N +FUdNQWy4geFeI8gfo7yf50cpO/9AAl27Xm1E4Ku260ISMAahOMikPuv3zxuX6KHV +T7Bzn1gbDajLjmoEpVSI8aLX+o2MEhFukdyTIjih011xcPT+2PB/6SdNFwMkKEeN +035eJ/sRUUp5NV+oly2kDjT9leGslCddFsIumKEugk4Pvs2gFjkTbirqkqvLDNJt +XbWy3IxYONNA0OUF8su+NA2/gkUCggQACxeVUMFU+KFKumxzXpgmMgMKEHTTspI1 +QKP5uvdGrOfnbvK6caj9DVs14Gb+bRmbnr0kg0oRvcoQrrr0xnSv5OICQ6FWNKUa +7vcaCoZ8maX3sA7tuKvMWHiF3PcDfj7AZ5lms6XPxOF/ARWRN2kyhOzp4W9GLigK +CWR2qkEK2UsOeJfTTvwOZvuVnMDgPdrgwXTPJJMex/uFSD/VAdWwx66voo6VCT0c +NKRY/cK253MVOrrZb30hCXmPtx1HT4GzvltZYggejYLX1FNMqg7ejVZpeoUvY/Ni +4J09TvCmkG5g9hY0lLeJdeWjPsgC6j6EX89s1dLB4q6N6ISHENg1mkH/3335PqZp +PJeETfa9MjdP/qjfZB6uhjuClVI101sxhwZMvouH2e7imrG3F2l6cHaVMhZ/ENKA +jP6ivfhR9/KPU644pGf+nHzSp75RcOjPLhHqfYkJjIj5cX61AXMiU2wH6tGgLdXX +WiSCuqAUpW4GSQl0n0V8tF6XIDbDVfulQ65HXErMPSeJRCfzmYCkSwbCCDH+55ZS +tQu+qPj8mDdeHz1Oujhc4VgkylSbirFHXbGNWU5j+6Jk7yL939sLdlURoyz6Wsud +i6LODLerD2EMe1nMNgNlsABjQmsV9eAjnrM+dURrDKfVm/UYsgSkcb6/sLOuhZDK +5SYFTXCD1N77w3N2SUbpRkDADrgiDtDKI5mGOxkmAa18Vk9RkVKSwSgfKurDZhGd +oDponrm1hpYKQl6gn7xMVLByZiLDUEwESSvPzHRksOd13HgNmrTZJMOYctAE4uyQ +XNZg0PjPJ5X1i7+Jjb5d9sMMwIMhAr2WYEnzxZ3FZaHSEneV0j3qNOjEAzoTAPRd +/Unrk3uuY1oor5f0EIHPddcATpfaNCaQt58zxtoVA8f/y1r9WXyvnGMT58MioZdC +ietH+CUhJnb2aHkpou8WeYP91OTi9C7zlKWTNyjkv7vE0ocnghrzsQTtVZ/AiJhi +VATCc/b7dmSHzML+waYlIMXue57JocQMCvIv/ho5e5MTA6CZYQ/QSQC2Q/GjYt0i +7ObbxfRZ5Ohdyb0X9FncuD6uty/lJXqfaKlQAP5OnvXOqEYROayhEMfY7924M44E +vJfJnpI6fBABEGNuw1thZaLqY7/ce7dHDBwgyNtIKnnj/I7YesTagFesR+JoQJGW +V7XUCP//RRP4QKG0BNdCL3iUFR72MebQy3wV29VFI7y32wv8H9wKHg5qgoWfdQyE +yeFwqtSOng0fHURzLeB0PjuU/hjjEHzfIzf5W4zoXdY3ngxX1SYXIzD36QVxnsiG +w1bAMxN9o2V8Be1gZCw1S1MtVK1+lvgsS2rKrWz0xfpYriWarWfsmw== +-----END RSA PRIVATE KEY-----`) + +var localhostCertShortEEKey = []byte(`-----BEGIN CERTIFICATE----- +MIICEzCCAXygAwIBAgIQMIMChMLGrR+QvmQvpwAU6zANBgkqhkiG9w0BAQsFADAS +MRAwDgYDVQQKEwdBY21lIENvMCAXDTcwMDEwMTAwMDAwMFoYDzIwODQwMTI5MTYw +MDAwWjASMRAwDgYDVQQKEwdBY21lIENvMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB +iQKBgQDuLnQAI3mDgey3VBzWnB2L39JUU4txjeVE6myuDqkM/uGlfjb9SjY1bIw4 +iA5sBBZzHi3z0h1YV8QPuxEbi4nW91IJm2gsvvZhIrCHS3l6afab4pZBl2+XsDul +rKBxKKtD1rGxlG4LjncdabFn9gvLZad2bSysqz/qTAUStTvqJQIDAQABo2gwZjAO +BgNVHQ8BAf8EBAMCAqQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUw +AwEB/zAuBgNVHREEJzAlggtleGFtcGxlLmNvbYcEfwAAAYcQAAAAAAAAAAAAAAAA +AAAAATANBgkqhkiG9w0BAQsFAAOBgQCEcetwO59EWk7WiJsG4x8SY+UIAA+flUI9 +tyC4lNhbcF2Idq9greZwbYCqTTTr2XiRNSMLCOjKyI7ukPoPjo16ocHj+P3vZGfs +h1fIw3cSS2OolhloGw/XM6RWPWtPAlGykKLciQrBru5NAPvCMsb/I1DAceTiotQM +fblo6RBxUQ== +-----END CERTIFICATE-----`) + +var localhostKeyShortEEKey = []byte(`-----BEGIN RSA PRIVATE KEY----- +MIICXgIBAAKBgQDuLnQAI3mDgey3VBzWnB2L39JUU4txjeVE6myuDqkM/uGlfjb9 +SjY1bIw4iA5sBBZzHi3z0h1YV8QPuxEbi4nW91IJm2gsvvZhIrCHS3l6afab4pZB +l2+XsDulrKBxKKtD1rGxlG4LjncdabFn9gvLZad2bSysqz/qTAUStTvqJQIDAQAB +AoGAGRzwwir7XvBOAy5tM/uV6e+Zf6anZzus1s1Y1ClbjbE6HXbnWWF/wbZGOpet +3Zm4vD6MXc7jpTLryzTQIvVdfQbRc6+MUVeLKwZatTXtdZrhu+Jk7hx0nTPy8Jcb +uJqFk541aEw+mMogY/xEcfbWd6IOkp+4xqjlFLBEDytgbIECQQDvH/E6nk+hgN4H +qzzVtxxr397vWrjrIgPbJpQvBsafG7b0dA4AFjwVbFLmQcj2PprIMmPcQrooz8vp +jy4SHEg1AkEA/v13/5M47K9vCxmb8QeD/asydfsgS5TeuNi8DoUBEmiSJwma7FXY +fFUtxuvL7XvjwjN5B30pNEbc6Iuyt7y4MQJBAIt21su4b3sjXNueLKH85Q+phy2U +fQtuUE9txblTu14q3N7gHRZB4ZMhFYyDy8CKrN2cPg/Fvyt0Xlp/DoCzjA0CQQDU +y2ptGsuSmgUtWj3NM9xuwYPm+Z/F84K6+ARYiZ6PYj013sovGKUFfYAqVXVlxtIX +qyUBnu3X9ps8ZfjLZO7BAkEAlT4R5Yl6cGhaJQYZHOde3JEMhNRcVFMO8dJDaFeo +f9Oeos0UUothgiDktdQHxdNEwLjQf7lJJBzV+5OtwswCWA== +-----END RSA PRIVATE KEY-----`) + +func startTestHTTPS(handler http.Handler, certificate []byte, privateKey []byte) *httptest.Server { + ts := httptest.NewUnstartedServer(handler) + cert, _ := tls.X509KeyPair(certificate, privateKey) + existingConfig := ts.TLS + if existingConfig != nil { + ts.TLS = existingConfig.Clone() + } else { + ts.TLS = new(tls.Config) + } + if ts.TLS.NextProtos == nil { + nextProtos := []string{"http/1.1"} + //if ts.EnableHTTP2 { // to be uncommented when go version is updated in build_servers + // nextProtos = []string{"h2"} + //} + ts.TLS.NextProtos = nextProtos + } + + ts.TLS.Certificates = []tls.Certificate{cert} + ts.StartTLS() + return ts +}