From 687c1b83f7a9c6d58bf6c2d4e802f59799cf85a7 Mon Sep 17 00:00:00 2001 From: Thomas Date: Sun, 7 Aug 2022 16:26:56 +0200 Subject: [PATCH 01/12] Update go.mod --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 3a3ca5d952..a372ff1b88 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/gofiber/fiber/v2 +module github.com/thomasdseao/fiber/v2 go 1.16 From 4942faedc9d1d880fd1aa65f21a39d31816a2d83 Mon Sep 17 00:00:00 2001 From: Thomas Date: Fri, 12 Aug 2022 15:50:53 +0200 Subject: [PATCH 02/12] wip --- app.go | 3 +++ ctx.go | 15 +++++++++++++++ listen.go | 31 ++++++++++++++++++++----------- 3 files changed, 38 insertions(+), 11 deletions(-) diff --git a/app.go b/app.go index d3523c1445..51e57b651a 100644 --- a/app.go +++ b/app.go @@ -366,6 +366,9 @@ type Config struct { // // Optional. Default: DefaultColors ColorScheme Colors `json:"color_scheme"` + + // TLS handler + tlsHandler *tlsHandler } // Static defines configuration options when defining static assets. diff --git a/ctx.go b/ctx.go index 004cf3ec7a..8b1989ed77 100644 --- a/ctx.go +++ b/ctx.go @@ -7,6 +7,7 @@ package fiber import ( "bytes" "context" + "crypto/tls" "encoding/json" "encoding/xml" "errors" @@ -65,6 +66,18 @@ type Ctx struct { fasthttp *fasthttp.RequestCtx // Reference to *fasthttp.RequestCtx matched bool // Non use route matched viewBindMap *dictpool.Dict // Default view map to bind template engine + tlsHandler *tlsHandler // Contains information from a ClientHello message in order to guide application logic +} + +// tlsHandle object +type tlsHandler struct { + clientHelloInfo *tls.ClientHelloInfo +} + +// GetClientInfo Callback function to set CHI +func (t *tlsHandler) GetClientInfo(info *tls.ClientHelloInfo) (*tls.Certificate, error) { + t.clientHelloInfo = info + return nil, nil } // Range data for c.Range @@ -130,6 +143,8 @@ func (app *App) AcquireCtx(fctx *fasthttp.RequestCtx) *Ctx { c.fasthttp = fctx // reset base uri c.baseURI = "" + // Attach tlsHandler object to context + c.tlsHandler = app.config.tlsHandler // Prettify path c.configDependentPaths() return c diff --git a/listen.go b/listen.go index 89a6fba6cb..33b6fbb448 100644 --- a/listen.go +++ b/listen.go @@ -81,22 +81,28 @@ func (app *App) ListenTLS(addr, certFile, keyFile string) error { if len(certFile) == 0 || len(keyFile) == 0 { return errors.New("tls: provide a valid cert or key path") } + // Set TLS config with handler + cert, err := tls.LoadX509KeyPair(certFile, keyFile) + if err != nil { + return fmt.Errorf("tls: cannot load TLS key pair from certFile=%q and keyFile=%q: %s", certFile, keyFile, err) + } + tlsHandler := &tlsHandler{} + config := &tls.Config{ + MinVersion: tls.VersionTLS12, + Certificates: []tls.Certificate{ + cert, + }, + GetCertificate: tlsHandler.GetClientInfo, + } // Prefork is supported if app.config.Prefork { - cert, err := tls.LoadX509KeyPair(certFile, keyFile) - if err != nil { - return fmt.Errorf("tls: cannot load TLS key pair from certFile=%q and keyFile=%q: %s", certFile, keyFile, err) - } - config := &tls.Config{ - MinVersion: tls.VersionTLS12, - Certificates: []tls.Certificate{ - cert, - }, - } return app.prefork(app.config.Network, addr, config) } + // Setup listener ln, err := net.Listen(app.config.Network, addr) + ln = tls.NewListener(ln, config) + if err != nil { return err } @@ -110,8 +116,11 @@ func (app *App) ListenTLS(addr, certFile, keyFile string) error { if app.config.EnablePrintRoutes { app.printRoutesMessage() } + // Attach the tlsHandler + app.config.tlsHandler = tlsHandler + // Start listening - return app.server.ServeTLS(ln, certFile, keyFile) + return app.server.Serve(ln) } // ListenMutualTLS serves HTTPS requests from the given addr. From d47abb2d5ede7f4a4ab2a5b45bad285f47e5015b Mon Sep 17 00:00:00 2001 From: Thomas Date: Fri, 12 Aug 2022 15:54:12 +0200 Subject: [PATCH 03/12] wip --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index a372ff1b88..3a3ca5d952 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/thomasdseao/fiber/v2 +module github.com/gofiber/fiber/v2 go 1.16 From 0a91b1f2ced71b2155f2c8223ddba77e1d58595b Mon Sep 17 00:00:00 2001 From: Thomas Date: Fri, 12 Aug 2022 21:26:52 +0200 Subject: [PATCH 04/12] wip --- ctx.go | 5 +++++ listen.go | 8 +++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/ctx.go b/ctx.go index 8b1989ed77..c6ca1f856f 100644 --- a/ctx.go +++ b/ctx.go @@ -805,6 +805,11 @@ func (c *Ctx) MultipartForm() (*multipart.Form, error) { return c.fasthttp.MultipartForm() } +// ClientHelloInfo return CHI from context +func (c *Ctx) ClientHelloInfo() *tls.ClientHelloInfo { + return c.tlsHandler.clientHelloInfo +} + // Next executes the next method in the stack that matches the current route. func (c *Ctx) Next() (err error) { // Increment handler index diff --git a/listen.go b/listen.go index 33b6fbb448..b2260c1c76 100644 --- a/listen.go +++ b/listen.go @@ -116,7 +116,8 @@ func (app *App) ListenTLS(addr, certFile, keyFile string) error { if app.config.EnablePrintRoutes { app.printRoutesMessage() } - // Attach the tlsHandler + + // Attach the tlsHandler to the config app.config.tlsHandler = tlsHandler // Start listening @@ -144,6 +145,7 @@ func (app *App) ListenMutualTLS(addr, certFile, keyFile, clientCertFile string) clientCertPool := x509.NewCertPool() clientCertPool.AppendCertsFromPEM(clientCACert) + tlsHandler := &tlsHandler{} config := &tls.Config{ MinVersion: tls.VersionTLS12, ClientAuth: tls.RequireAndVerifyClientCert, @@ -151,6 +153,7 @@ func (app *App) ListenMutualTLS(addr, certFile, keyFile, clientCertFile string) Certificates: []tls.Certificate{ cert, }, + GetCertificate: tlsHandler.GetClientInfo, } // Prefork is supported @@ -177,6 +180,9 @@ func (app *App) ListenMutualTLS(addr, certFile, keyFile, clientCertFile string) app.printRoutesMessage() } + // Attach the tlsHandler to the config + app.config.tlsHandler = tlsHandler + // Start listening return app.server.Serve(ln) } From 64bd24d94d180fabbcb085429d9092eedf15727e Mon Sep 17 00:00:00 2001 From: Thomas Date: Fri, 12 Aug 2022 23:39:36 +0200 Subject: [PATCH 05/12] wip --- ctx_test.go | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/ctx_test.go b/ctx_test.go index 325b67d78b..d44e2f3244 100644 --- a/ctx_test.go +++ b/ctx_test.go @@ -1247,6 +1247,28 @@ func Test_Ctx_Method(t *testing.T) { utils.AssertEqual(t, MethodPost, c.Method()) } +// go test -run Test_Ctx_ClientHelloInfo +func Test_Ctx_ClientHelloInfo(t *testing.T) { + t.Parallel() + app := New() + app.Post("/test", func(c *Ctx) error { + result := c.ClientHelloInfo() + if result != nil { + panic("Invalid ClientHelloInfo, it should be nil") + } + + return c.SendString("ClientHelloInfo is nil") + }) + + fctx := &fasthttp.RequestCtx{} + fctx.Request.Header.SetMethod(MethodPost) + fctx.Request.SetRequestURI("/test") + + app.Handler()(fctx) + fmt.Println(fctx.Response.Body()) + utils.AssertEqual(t, []byte("ClientHelloInfo is nil"), fctx.Response.Body()) +} + // go test -run Test_Ctx_InvalidMethod func Test_Ctx_InvalidMethod(t *testing.T) { t.Parallel() From 278b20940f8da44f255ef129550efa0e51a839e4 Mon Sep 17 00:00:00 2001 From: Thomas Date: Fri, 12 Aug 2022 23:39:57 +0200 Subject: [PATCH 06/12] wip --- ctx.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ctx.go b/ctx.go index c6ca1f856f..1980877853 100644 --- a/ctx.go +++ b/ctx.go @@ -807,7 +807,11 @@ func (c *Ctx) MultipartForm() (*multipart.Form, error) { // ClientHelloInfo return CHI from context func (c *Ctx) ClientHelloInfo() *tls.ClientHelloInfo { - return c.tlsHandler.clientHelloInfo + if c.tlsHandler != nil { + return c.tlsHandler.clientHelloInfo + } + + return nil } // Next executes the next method in the stack that matches the current route. From df21365d116a9444ab463beb16ad3476266a1d9e Mon Sep 17 00:00:00 2001 From: Thomas Date: Sat, 13 Aug 2022 00:00:56 +0200 Subject: [PATCH 07/12] Move tlsHandler from Config to App --- app.go | 5 ++--- ctx.go | 2 +- listen.go | 4 ++-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/app.go b/app.go index 51e57b651a..95b5fd13db 100644 --- a/app.go +++ b/app.go @@ -112,6 +112,8 @@ type App struct { // Latest route & group latestRoute *Route latestGroup *Group + // TLS handler + tlsHandler *tlsHandler } // Config is a struct holding the server settings. @@ -366,9 +368,6 @@ type Config struct { // // Optional. Default: DefaultColors ColorScheme Colors `json:"color_scheme"` - - // TLS handler - tlsHandler *tlsHandler } // Static defines configuration options when defining static assets. diff --git a/ctx.go b/ctx.go index 1980877853..c64fadb49f 100644 --- a/ctx.go +++ b/ctx.go @@ -144,7 +144,7 @@ func (app *App) AcquireCtx(fctx *fasthttp.RequestCtx) *Ctx { // reset base uri c.baseURI = "" // Attach tlsHandler object to context - c.tlsHandler = app.config.tlsHandler + c.tlsHandler = app.tlsHandler // Prettify path c.configDependentPaths() return c diff --git a/listen.go b/listen.go index b2260c1c76..55aa3eddc5 100644 --- a/listen.go +++ b/listen.go @@ -118,7 +118,7 @@ func (app *App) ListenTLS(addr, certFile, keyFile string) error { } // Attach the tlsHandler to the config - app.config.tlsHandler = tlsHandler + app.tlsHandler = tlsHandler // Start listening return app.server.Serve(ln) @@ -181,7 +181,7 @@ func (app *App) ListenMutualTLS(addr, certFile, keyFile, clientCertFile string) } // Attach the tlsHandler to the config - app.config.tlsHandler = tlsHandler + app.tlsHandler = tlsHandler // Start listening return app.server.Serve(ln) From 8ffa4e38f89bd6404f64ccb1464d235373560a94 Mon Sep 17 00:00:00 2001 From: Thomas Date: Sat, 13 Aug 2022 00:06:56 +0200 Subject: [PATCH 08/12] Use NewError instead of panic --- ctx_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ctx_test.go b/ctx_test.go index d44e2f3244..5820c27dd6 100644 --- a/ctx_test.go +++ b/ctx_test.go @@ -1254,7 +1254,7 @@ func Test_Ctx_ClientHelloInfo(t *testing.T) { app.Post("/test", func(c *Ctx) error { result := c.ClientHelloInfo() if result != nil { - panic("Invalid ClientHelloInfo, it should be nil") + return NewError(500, "Invalid ClientHelloInfo, it should be nil") } return c.SendString("ClientHelloInfo is nil") From 070077920d1bc9124c0bfb61fb2dcf06f7694d94 Mon Sep 17 00:00:00 2001 From: Thomas Date: Sat, 13 Aug 2022 00:30:04 +0200 Subject: [PATCH 09/12] Add a test with ServerName --- ctx_test.go | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/ctx_test.go b/ctx_test.go index 5820c27dd6..324de68f50 100644 --- a/ctx_test.go +++ b/ctx_test.go @@ -12,6 +12,7 @@ import ( "bytes" "compress/gzip" "context" + "crypto/tls" "errors" "fmt" "io" @@ -1254,19 +1255,24 @@ func Test_Ctx_ClientHelloInfo(t *testing.T) { app.Post("/test", func(c *Ctx) error { result := c.ClientHelloInfo() if result != nil { - return NewError(500, "Invalid ClientHelloInfo, it should be nil") + return c.SendString(result.ServerName) } return c.SendString("ClientHelloInfo is nil") }) - fctx := &fasthttp.RequestCtx{} - fctx.Request.Header.SetMethod(MethodPost) - fctx.Request.SetRequestURI("/test") + // Test without TLS handler + resp, _ := app.Test(httptest.NewRequest(MethodPost, "/test", nil)) + body, _ := ioutil.ReadAll(resp.Body) + utils.AssertEqual(t, []byte("ClientHelloInfo is nil"), body) - app.Handler()(fctx) - fmt.Println(fctx.Response.Body()) - utils.AssertEqual(t, []byte("ClientHelloInfo is nil"), fctx.Response.Body()) + // Test with TLS Handler + app.tlsHandler = &tlsHandler{clientHelloInfo: &tls.ClientHelloInfo{ + ServerName: "example.golang", + }} + resp, _ = app.Test(httptest.NewRequest(MethodPost, "/test", nil)) + body, _ = ioutil.ReadAll(resp.Body) + utils.AssertEqual(t, []byte("example.golang"), body) } // go test -run Test_Ctx_InvalidMethod From 8b355a220301aa1768c850f349401b19e37cb1a4 Mon Sep 17 00:00:00 2001 From: Thomas Date: Sat, 13 Aug 2022 00:50:12 +0200 Subject: [PATCH 10/12] Add some tests on ClientHelloInfo --- ctx_test.go | 42 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/ctx_test.go b/ctx_test.go index 324de68f50..034cfbb15e 100644 --- a/ctx_test.go +++ b/ctx_test.go @@ -1252,7 +1252,7 @@ func Test_Ctx_Method(t *testing.T) { func Test_Ctx_ClientHelloInfo(t *testing.T) { t.Parallel() app := New() - app.Post("/test", func(c *Ctx) error { + app.Get("/ServerName", func(c *Ctx) error { result := c.ClientHelloInfo() if result != nil { return c.SendString(result.ServerName) @@ -1260,19 +1260,53 @@ func Test_Ctx_ClientHelloInfo(t *testing.T) { return c.SendString("ClientHelloInfo is nil") }) + app.Get("/SignatureSchemes", func(c *Ctx) error { + result := c.ClientHelloInfo() + if result != nil { + return c.JSON(result.SignatureSchemes) + } + + return c.SendString("ClientHelloInfo is nil") + }) + app.Get("/SupportedVersions", func(c *Ctx) error { + result := c.ClientHelloInfo() + if result != nil { + return c.JSON(result.SupportedVersions) + } + + return c.SendString("ClientHelloInfo is nil") + }) // Test without TLS handler - resp, _ := app.Test(httptest.NewRequest(MethodPost, "/test", nil)) + resp, _ := app.Test(httptest.NewRequest(MethodGet, "/ServerName", nil)) body, _ := ioutil.ReadAll(resp.Body) utils.AssertEqual(t, []byte("ClientHelloInfo is nil"), body) // Test with TLS Handler + const ( + PSSWithSHA256 = 0x0804 + VersionTLS13 = 0x0304 + ) app.tlsHandler = &tlsHandler{clientHelloInfo: &tls.ClientHelloInfo{ - ServerName: "example.golang", + ServerName: "example.golang", + SignatureSchemes: []tls.SignatureScheme{PSSWithSHA256}, + SupportedVersions: []uint16{VersionTLS13}, }} - resp, _ = app.Test(httptest.NewRequest(MethodPost, "/test", nil)) + + // Test ServerName + resp, _ = app.Test(httptest.NewRequest(MethodGet, "/ServerName", nil)) body, _ = ioutil.ReadAll(resp.Body) utils.AssertEqual(t, []byte("example.golang"), body) + + // Test SignatureSchemes + resp, _ = app.Test(httptest.NewRequest(MethodGet, "/SignatureSchemes", nil)) + body, _ = ioutil.ReadAll(resp.Body) + utils.AssertEqual(t, "["+strconv.Itoa(PSSWithSHA256)+"]", string(body)) + + // Test SupportedVersions + resp, _ = app.Test(httptest.NewRequest(MethodGet, "/SupportedVersions", nil)) + body, _ = ioutil.ReadAll(resp.Body) + utils.AssertEqual(t, "["+strconv.Itoa(VersionTLS13)+"]", string(body)) } // go test -run Test_Ctx_InvalidMethod From 3462689908b86d67fddf619afb00644eb68fc27e Mon Sep 17 00:00:00 2001 From: wernerr Date: Thu, 18 Aug 2022 10:21:09 +0200 Subject: [PATCH 11/12] fix missing import --- ctx_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/ctx_test.go b/ctx_test.go index b2e871fce5..825cbb8966 100644 --- a/ctx_test.go +++ b/ctx_test.go @@ -13,6 +13,7 @@ import ( "compress/gzip" "context" "crypto/tls" + "encoding/xml" "errors" "fmt" "io" From 4b0f9c92298bc11d89927eb9fbffdf089208bf6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Muhammed=20Efe=20=C3=87etin?= Date: Thu, 18 Aug 2022 18:23:47 +0300 Subject: [PATCH 12/12] remove unnecessary ctx field. --- ctx.go | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/ctx.go b/ctx.go index 61e7ec69a0..d8818ff855 100644 --- a/ctx.go +++ b/ctx.go @@ -66,7 +66,6 @@ type Ctx struct { fasthttp *fasthttp.RequestCtx // Reference to *fasthttp.RequestCtx matched bool // Non use route matched viewBindMap *dictpool.Dict // Default view map to bind template engine - tlsHandler *tlsHandler // Contains information from a ClientHello message in order to guide application logic } // tlsHandle object @@ -143,8 +142,6 @@ func (app *App) AcquireCtx(fctx *fasthttp.RequestCtx) *Ctx { c.fasthttp = fctx // reset base uri c.baseURI = "" - // Attach tlsHandler object to context - c.tlsHandler = app.tlsHandler // Prettify path c.configDependentPaths() return c @@ -814,8 +811,8 @@ func (c *Ctx) MultipartForm() (*multipart.Form, error) { // ClientHelloInfo return CHI from context func (c *Ctx) ClientHelloInfo() *tls.ClientHelloInfo { - if c.tlsHandler != nil { - return c.tlsHandler.clientHelloInfo + if c.app.tlsHandler != nil { + return c.app.tlsHandler.clientHelloInfo } return nil