Low level TLS handshake?

Issue

I’d like to intercept ALPN selection and select the one I want instead of the first common one between the client and the server.

Code:

// we have some ALPN protocols and certificates for TLS/SSL
tlsConfig := &tls.Config {
    Certificates: serverCertificates,
    NextProtos  : serverALPN,
}
// a simple TCP server
server, err := net.Listen("tcp", serverHost+":"+serverPort) 
...
for {
    // we accept a connection
    conn, err := ln.Accept()
    ...
    // wrap it in TLS
    tlsConn := tls.Server(conn, &tlsConfig)
    // and pass it to the handler
    go handleConnection(tlsConn)
}

So far we didn’t do any TLS handshaking, so the connection is idle, pure. In func handleConnection(conn *tls.Conn) we would err := conn.Handshake() to perform the handshaking automatically for us, but how to do it manually? I didn’t seem to find any info on that in tls module documentation. I’d like to do something like this:

// we communicate with client until he's told us all the ALPNs they support
state := conn.HandshakeUntilALPN()
// we got the list, now we use some algorithm to choose the ALPN
ALPN := myALPNAlgorithm(state.listOfALPNsFromClient)
// after that we tell the client which algo we've chosen
conn.SendALPN(ALPN)
// and we continue the handshake
conn.ContinueHandshake()
...

Of course it’s silly pseudo-pseudo code, but hopefully you get the idea 🙂

Ideally, I’d like to know that for both the Server and the Client, if it’s possible at all.

Solution

the answer is in the crypto library:
https://pkg.go.dev/crypto/tls

these papers might be useful:

https://developpaper.com/the-principle-of-https-and-golang-specifies-the-https-cipher-suite/

and

https://eli.thegreenplace.net/2021/go-https-servers-with-tls/

You will need to build your own server and client. TLSlistenandserve is an abstraction. you will have to build your own listenandserve.

Answered By – prr

Answer Checked By – Clifford M. (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.