"runtime/debug",
        },
        "net/http/internal":  {"L4"},
-       "net/http/httptrace": {"context", "internal/nettrace", "net", "reflect", "time"},
+       "net/http/httptrace": {"context", "crypto/tls", "internal/nettrace", "net", "reflect", "time"},
 
        // HTTP-using packages.
        "expvar":             {"L4", "OS", "encoding/json", "net/http"},
 
 
 import (
        "context"
+       "crypto/tls"
        "internal/nettrace"
        "net"
        "reflect"
        // enabled, this may be called multiple times.
        ConnectDone func(network, addr string, err error)
 
+       // TLSHandshakeStart is called when the TLS handshake is started. When
+       // connecting to a HTTPS site via a HTTP proxy, the handshake happens after
+       // the CONNECT request is processed by the proxy.
+       TLSHandshakeStart func()
+
+       // TLSHandshakeDone is called after the TLS handshake with either the
+       // successful handshake's connection state, or a non-nil error on handshake
+       // failure.
+       TLSHandshakeDone func(tls.ConnectionState, error)
+
        // WroteHeaders is called after the Transport has written
        // the request headers.
        WroteHeaders func()
 
                writeErrCh:    make(chan error, 1),
                writeLoopDone: make(chan struct{}),
        }
+       trace := httptrace.ContextClientTrace(ctx)
        tlsDial := t.DialTLS != nil && cm.targetScheme == "https" && cm.proxyURL == nil
        if tlsDial {
                var err error
                if tc, ok := pconn.conn.(*tls.Conn); ok {
                        // Handshake here, in case DialTLS didn't. TLSNextProto below
                        // depends on it for knowing the connection state.
+                       if trace != nil && trace.TLSHandshakeStart != nil {
+                               trace.TLSHandshakeStart()
+                       }
                        if err := tc.Handshake(); err != nil {
                                go pconn.conn.Close()
+                               if trace != nil && trace.TLSHandshakeDone != nil {
+                                       trace.TLSHandshakeDone(tls.ConnectionState{}, err)
+                               }
                                return nil, err
                        }
                        cs := tc.ConnectionState()
+                       if trace != nil && trace.TLSHandshakeDone != nil {
+                               trace.TLSHandshakeDone(cs, nil)
+                       }
                        pconn.tlsState = &cs
                }
        } else {
                        })
                }
                go func() {
+                       if trace != nil && trace.TLSHandshakeStart != nil {
+                               trace.TLSHandshakeStart()
+                       }
                        err := tlsConn.Handshake()
                        if timer != nil {
                                timer.Stop()
                }()
                if err := <-errc; err != nil {
                        plainConn.Close()
+                       if trace != nil && trace.TLSHandshakeDone != nil {
+                               trace.TLSHandshakeDone(tls.ConnectionState{}, err)
+                       }
                        return nil, err
                }
                if !cfg.InsecureSkipVerify {
                        }
                }
                cs := tlsConn.ConnectionState()
+               if trace != nil && trace.TLSHandshakeDone != nil {
+                       trace.TLSHandshakeDone(cs, nil)
+               }
                pconn.tlsState = &cs
                pconn.conn = tlsConn
        }
 
                        close(gotWroteReqEvent)
                },
        }
+       if h2 {
+               trace.TLSHandshakeStart = func() { logf("tls handshake start") }
+               trace.TLSHandshakeDone = func(s tls.ConnectionState, err error) {
+                       logf("tls handshake done. ConnectionState = %v \n err = %v", s, err)
+               }
+       }
        if noHooks {
                // zero out all func pointers, trying to get some path to crash
                *trace = httptrace.ClientTrace{}
        wantOnceOrMore("connected to tcp " + addrStr + " = <nil>")
        wantOnce("Reused:false WasIdle:false IdleTime:0s")
        wantOnce("first response byte")
-       if !h2 {
+       if h2 {
+               wantOnce("tls handshake start")
+               wantOnce("tls handshake done")
+       } else {
                wantOnce("PutIdleConn = <nil>")
        }
        wantOnce("Wait100Continue")
        }
 }
 
+// Test the httptrace.TLSHandshake{Start,Done} hooks with a https http1
+// connections. The http2 test is done in TestTransportEventTrace_h2
+func TestTLSHandshakeTrace(t *testing.T) {
+       defer afterTest(t)
+       s := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
+       defer s.Close()
+
+       var mu sync.Mutex
+       var start, done bool
+       trace := &httptrace.ClientTrace{
+               TLSHandshakeStart: func() {
+                       mu.Lock()
+                       defer mu.Unlock()
+                       start = true
+               },
+               TLSHandshakeDone: func(s tls.ConnectionState, err error) {
+                       mu.Lock()
+                       defer mu.Unlock()
+                       done = true
+                       if err != nil {
+                               t.Fatal("Expected error to be nil but was:", err)
+                       }
+               },
+       }
+
+       tr := &Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}
+       defer tr.CloseIdleConnections()
+       c := &Client{Transport: tr}
+       req, err := NewRequest("GET", s.URL, nil)
+       if err != nil {
+               t.Fatal("Unable to construct test request:", err)
+       }
+       req = req.WithContext(httptrace.WithClientTrace(req.Context(), trace))
+
+       r, err := c.Do(req)
+       if err != nil {
+               t.Fatal("Unexpected error making request:", err)
+       }
+       r.Body.Close()
+       mu.Lock()
+       defer mu.Unlock()
+       if !start {
+               t.Fatal("Expected TLSHandshakeStart to be called, but wasn't")
+       }
+       if !done {
+               t.Fatal("Expected TLSHandshakeDone to be called, but wasnt't")
+       }
+}
+
 func TestTransportMaxIdleConns(t *testing.T) {
        defer afterTest(t)
        ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {