fasthttp icon indicating copy to clipboard operation
fasthttp copied to clipboard

tls.ClientHelloInfo in http handlers

Open petuxodev opened this issue 3 years ago • 4 comments

Please, expose ClientHelloInfo in http handlers, it really matters for me.

petuxodev avatar Jul 05 '22 21:07 petuxodev

You can create your own listener, accept connections (record the and pass them to fasthttp using Server.ServeConn.

Otherwise a pull request to somehow add this information to RequestCtx is always welcome.

erikdubbelboer avatar Jul 06 '22 07:07 erikdubbelboer

Hi @petuxodev, @erikdubbelboer I'd like to work on this issue. It seems to the simplest solution to get *tls.ClientHelloInfo using TLSConfig.GetCertificate hooks below this.

@@ -1721,7 +1730,12 @@ func (s *Server) AppendCertEmbed(certData, keyData []byte) error {

 func (s *Server) configTLS() {
        if s.TLSConfig == nil {
-               s.TLSConfig = &tls.Config{}
+               s.TLSConfig = &tls.Config{
+                       GetCertificate: func(hello *tls.ClientHelloInfo) (*tls.Certificate, error) {
+                               s.clientHelloInfo = hello
+                               return nil, nil
+                       },
+               }
        }
 }

@@ -2086,6 +2100,9 @@ func (s *Server) serveConn(c net.Conn) (err error) {
        ctx := s.acquireCtx(c)
        ctx.connTime = connTime
        isTLS := ctx.IsTLS()
+       if isTLS {
+               ctx.clientHelloInfo = s.clientHelloInfo
+       }
        var (
                br *bufio.Reader
                bw *bufio.Writer

l'd like to know what is the purpose of the issue to implement this feature tests. Do you wanna only get the Servername? or the entire clientHelloInfo to earn the availabilities for a client encryption details (such as tls versions, CipherSuites and so on...)?

https://pkg.go.dev/crypto/tls#ClientHelloInfo

u5surf avatar Aug 26 '22 09:08 u5surf

Good questions, lets wait for @petuxodev to answer.

Your solution is not going to work. A server can have a lot of concurrent connections so you can't use a variable on Server to keep track of a single connection.

erikdubbelboer avatar Aug 26 '22 09:08 erikdubbelboer

Hi @petuxodev, @erikdubbelboer I'd like to work on this issue. It seems to the simplest solution to get *tls.ClientHelloInfo using TLSConfig.GetCertificate hooks below this.

@@ -1721,7 +1730,12 @@ func (s *Server) AppendCertEmbed(certData, keyData []byte) error {

 func (s *Server) configTLS() {
        if s.TLSConfig == nil {
-               s.TLSConfig = &tls.Config{}
+               s.TLSConfig = &tls.Config{
+                       GetCertificate: func(hello *tls.ClientHelloInfo) (*tls.Certificate, error) {
+                               s.clientHelloInfo = hello
+                               return nil, nil
+                       },
+               }
        }
 }

@@ -2086,6 +2100,9 @@ func (s *Server) serveConn(c net.Conn) (err error) {
        ctx := s.acquireCtx(c)
        ctx.connTime = connTime
        isTLS := ctx.IsTLS()
+       if isTLS {
+               ctx.clientHelloInfo = s.clientHelloInfo
+       }
        var (
                br *bufio.Reader
                bw *bufio.Writer

l'd like to know what is the purpose of the issue to implement this feature tests. Do you wanna only get the Servername? or the entire clientHelloInfo to earn the availabilities for a client encryption details (such as tls versions, CipherSuites and so on...)?

https://pkg.go.dev/crypto/tls#ClientHelloInfo

I think he wants to use something like Ja3 fingerprinting, but this feature released in Fiber.

ja3abuser avatar Aug 26 '22 19:08 ja3abuser