Client access to TLS Session-ID

234 views
Skip to first unread message

laszlo...@forgerock.com

unread,
Nov 22, 2016, 9:08:12 AM11/22/16
to golang-nuts
Hi, 

I'd like to implement a Client app in go which accesses to a Java HTTPS server and it uses the TLS Session-ID to protect against Man-in-the-middle attack and bind to one single TLS Session. When I use the Java Servlet the specification http://download.oracle.com/otn-pub/jcp/servlet-3.0-fr-eval-oth-JSpec/servlet-3_0-final-spec.pdf expose the "javax.servlet.request.ssl_session_id" property and I have access to TLS Session-ID something like "032554E059DB27BF8CD87EBC53E9FF29376265F0BBFDBBFB7773D2277E5559F5"

Also when I use the $ openssl s_client -connect www.google.com:443 I get the  Session-ID too
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES128-GCM-SHA256
    Session-ID: 38950231484EDAA2E55951FB86CBCED2A2A6074B6E1C5285B354626434397694

How can I access to the same information in Go?

I'm working with this code to access to Session-ID somehow but it looks like inaccessible from https://github.com/golang/go/blob/master/src/crypto/tls/handshake_client.go 

I'd appreciate any help or guidance about how can I fetch the Session-ID of a TLS connection.  

Thank you in advance. 

func main() {
log.SetFlags(log.Lshortfile)

tr := &http.Transport{
DialTLS: dialTLSDefault,
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
httpClient := &http.Client{Transport: tr}

res, err := httpClient.Get("https://www.google.com/robots.txt")
if err != nil {
log.Fatal(err)
}
defer res.Body.Close()
robots, err := ioutil.ReadAll(res.Body)
if err != nil {
log.Fatal(err)
}

fmt.Printf("%s", robots)

}

func dialTLSDefault(network, addr string) (net.Conn, error) {
fmt.Printf("Connecto to: %s %s\n ", network, addr)
cfg := &tls.Config{
InsecureSkipVerify: true,
ClientSessionCache: tls.NewLRUClientSessionCache(2),
ServerName:"www.google.com",

}
cn, err := tls.Dial(network, addr, cfg)
if err != nil {
return nil, err
}
if err := cn.Handshake(); err != nil {
return nil, err
}
if !cfg.InsecureSkipVerify {
if err := cn.VerifyHostname(cfg.ServerName); err != nil {
return nil, err
}
}
state := cn.ConnectionState()

if !state.NegotiatedProtocolIsMutual {
return nil, errors.New("http: could not negotiate protocol mutually")
}

fmt.Printf("NegotiatedProtocol: %s\n ", state.NegotiatedProtocol)
fmt.Printf("TLSUnique: %s\n ", hex.EncodeToString(state.TLSUnique))
fmt.Printf("Session-ID: %s\n ", ????)

return cn, nil
}

Reply all
Reply to author
Forward
0 new messages