| Index: web_page_replay_go/src/webpagereplay/certs.go
|
| diff --git a/web_page_replay_go/src/webpagereplay/certs.go b/web_page_replay_go/src/webpagereplay/certs.go
|
| index 57e802c8db06ee5cfea337a01fb6bbbd8b46c8f0..11c80f443c2622255c5363c35e41dc6019e4e241 100644
|
| --- a/web_page_replay_go/src/webpagereplay/certs.go
|
| +++ b/web_page_replay_go/src/webpagereplay/certs.go
|
| @@ -22,8 +22,7 @@ func ReplayTLSConfig(root tls.Certificate, a *Archive) (*tls.Config, error) {
|
| }
|
| tp := &tlsProxy{&root, root_cert, a, nil}
|
| return &tls.Config{
|
| - Certificates: []tls.Certificate{*tp.root},
|
| - GetCertificate: tp.getReplayCertificate,
|
| + GetConfigForClient: tp.getReplayConfigForClient,
|
| }, nil
|
| }
|
|
|
| @@ -36,8 +35,7 @@ func RecordTLSConfig(root tls.Certificate, w *WritableArchive) (*tls.Config, err
|
| }
|
| tp := &tlsProxy{&root, root_cert, nil, w}
|
| return &tls.Config{
|
| - Certificates: []tls.Certificate{*tp.root},
|
| - GetCertificate: tp.getCertificate,
|
| + GetConfigForClient: tp.getRecordConfigForClient,
|
| }, nil
|
| }
|
|
|
| @@ -64,39 +62,50 @@ type tlsProxy struct {
|
| // served by the same IP. We can then run a DNS proxy that maps all hostnames in the
|
| // same equivalence class to the same local port, which models the possibility that
|
| // every equivalence class of hostnames can be served over the same HTTP/2 connection.
|
| -//
|
| -// getCertificate implements a callback for tls.Config.GetCertificate.
|
| -func (tp *tlsProxy) getReplayCertificate(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error) {
|
| +func (tp *tlsProxy) getReplayConfigForClient(clientHello *tls.ClientHelloInfo) (*tls.Config, error) {
|
| h := clientHello.ServerName
|
| if h == "" {
|
| - return tp.root, nil
|
| + return &tls.Config{
|
| + Certificates: []tls.Certificate{*tp.root},
|
| + }, nil
|
| }
|
|
|
| - der_bytes, err := tp.archive.FindHostCert(h)
|
| + der_bytes, negotiatedProtocol, err := tp.archive.FindHostTlsConfig(h)
|
| if err != nil || der_bytes == nil {
|
| return nil, fmt.Errorf("No archived cert for %s", h)
|
| }
|
| - return &tls.Certificate{
|
| - Certificate: [][]byte{der_bytes},
|
| - PrivateKey: tp.root.PrivateKey,
|
| + return &tls.Config{
|
| + Certificates: []tls.Certificate{
|
| + tls.Certificate{
|
| + Certificate: [][]byte{der_bytes},
|
| + PrivateKey: tp.root.PrivateKey,
|
| + }},
|
| + NextProtos: []string{negotiatedProtocol},
|
| }, nil
|
| }
|
|
|
| -func (tp *tlsProxy) getCertificate(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error) {
|
| +func (tp *tlsProxy) getRecordConfigForClient(clientHello *tls.ClientHelloInfo) (*tls.Config, error) {
|
| h := clientHello.ServerName
|
| if h == "" {
|
| - return tp.root, nil
|
| + return &tls.Config{
|
| + Certificates: []tls.Certificate{*tp.root},
|
| + }, nil
|
| }
|
| -
|
| - der_bytes, err := tp.writable_archive.FindHostCert(h)
|
| + der_bytes, negotiatedProtocol, err := tp.writable_archive.Archive.FindHostTlsConfig(h)
|
| if err == nil && der_bytes != nil {
|
| - return &tls.Certificate{
|
| - Certificate: [][]byte{der_bytes},
|
| - PrivateKey: tp.root.PrivateKey,
|
| + return &tls.Config{
|
| + Certificates: []tls.Certificate{
|
| + tls.Certificate{
|
| + Certificate: [][]byte{der_bytes},
|
| + PrivateKey: tp.root.PrivateKey,
|
| + }},
|
| + NextProtos: []string{negotiatedProtocol},
|
| }, nil
|
| }
|
|
|
| - conn, err := tls.Dial("tcp", fmt.Sprintf("%s:443", h), nil)
|
| + conn, err := tls.Dial("tcp", fmt.Sprintf("%s:443", h), &tls.Config{
|
| + NextProtos: []string{"h2", "http/1.1"},
|
| + })
|
| if err != nil {
|
| return nil, fmt.Errorf("Couldn't reach host %s: %v", h, err)
|
| }
|
| @@ -121,9 +130,15 @@ func (tp *tlsProxy) getCertificate(clientHello *tls.ClientHelloInfo) (*tls.Certi
|
| if err != nil {
|
| return nil, fmt.Errorf("create cert failed: %v", err)
|
| }
|
| - tp.writable_archive.RecordCert(h, der_bytes)
|
| - return &tls.Certificate{
|
| - Certificate: [][]byte{der_bytes},
|
| - PrivateKey: tp.root.PrivateKey,
|
| +
|
| + negotiatedProtocol = conn.ConnectionState().NegotiatedProtocol
|
| + tp.writable_archive.RecordTlsConfig(h, der_bytes, negotiatedProtocol)
|
| +
|
| + return &tls.Config{
|
| + Certificates: []tls.Certificate{
|
| + tls.Certificate{
|
| + Certificate: [][]byte{der_bytes},
|
| + PrivateKey: tp.root.PrivateKey}},
|
| + NextProtos: []string{negotiatedProtocol},
|
| }, nil
|
| }
|
|
|