mirror of
https://github.com/refraction-networking/utls.git
synced 2025-04-01 19:17:36 +03:00
fix: ech for hellogolang
This commit is contained in:
parent
3d730b9fb2
commit
fa88bd57f1
5 changed files with 213 additions and 168 deletions
|
@ -2,6 +2,9 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
// "crypto/tls"
|
||||||
|
"encoding/base64"
|
||||||
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
@ -24,13 +27,13 @@ var (
|
||||||
// var requestAddr = "crypto.cloudflare.com:443"
|
// var requestAddr = "crypto.cloudflare.com:443"
|
||||||
// var requestPath = "/cdn-cgi/trace"
|
// var requestPath = "/cdn-cgi/trace"
|
||||||
|
|
||||||
// var requestHostname = "tls-ech.dev" // speaks http2 and TLS 1.3 and ECH and PQ
|
var requestHostname = "tls-ech.dev" // speaks http2 and TLS 1.3 and ECH and PQ
|
||||||
// var requestAddr = "tls-ech.dev:443"
|
var requestAddr = "tls-ech.dev:443"
|
||||||
// var requestPath = "/"
|
var requestPath = "/"
|
||||||
|
|
||||||
var requestHostname = "defo.ie" // speaks http2 and TLS 1.3 and ECH and PQ
|
// var requestHostname = "defo.ie" // speaks http2 and TLS 1.3 and ECH and PQ
|
||||||
var requestAddr = "defo.ie:443"
|
// var requestAddr = "defo.ie:443"
|
||||||
var requestPath = "/ech-check.php"
|
// var requestPath = "/ech-check.php"
|
||||||
|
|
||||||
// var requestHostname = "client.tlsfingerprint.io" // speaks http2 and TLS 1.3 and ECH and PQ
|
// var requestHostname = "client.tlsfingerprint.io" // speaks http2 and TLS 1.3 and ECH and PQ
|
||||||
// var requestAddr = "client.tlsfingerprint.io:443"
|
// var requestAddr = "client.tlsfingerprint.io:443"
|
||||||
|
@ -41,29 +44,37 @@ func HttpGetCustom(hostname string, addr string) (*http.Response, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("os.OpenFile error: %+v", err)
|
return nil, fmt.Errorf("os.OpenFile error: %+v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
echConf, err := base64.RawStdEncoding.DecodeString("AEn+DQBFKwAgACABWIHUGj4u+PIggYXcR5JF0gYk3dCRioBW8uJq9H4mKAAIAAEAAQABAANAEnB1YmxpYy50bHMtZWNoLmRldgAA")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
config := tls.Config{
|
config := tls.Config{
|
||||||
ServerName: hostname,
|
ServerName: hostname,
|
||||||
KeyLogWriter: klw,
|
KeyLogWriter: klw,
|
||||||
|
EncryptedClientHelloConfigList: echConf,
|
||||||
}
|
}
|
||||||
dialConn, err := net.DialTimeout("tcp", addr, dialTimeout)
|
dialConn, err := net.DialTimeout("tcp", addr, dialTimeout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("net.DialTimeout error: %+v", err)
|
return nil, fmt.Errorf("net.DialTimeout error: %+v", err)
|
||||||
}
|
}
|
||||||
uTlsConn := tls.UClient(dialConn, &config, tls.HelloCustom)
|
uTlsConn := tls.UClient(dialConn, &config, tls.HelloGolang)
|
||||||
|
// uTlsConn := tls.Client(dialConn, &config)
|
||||||
defer uTlsConn.Close()
|
defer uTlsConn.Close()
|
||||||
|
|
||||||
// do not use this particular spec in production
|
// do not use this particular spec in production
|
||||||
// make sure to generate a separate copy of ClientHelloSpec for every connection
|
// make sure to generate a separate copy of ClientHelloSpec for every connection
|
||||||
spec, err := tls.UTLSIdToSpec(tls.HelloChrome_120)
|
// spec, err := tls.UTLSIdToSpec(tls.HelloChrome_120)
|
||||||
// spec, err := tls.UTLSIdToSpec(tls.HelloFirefox_120)
|
// // spec, err := tls.UTLSIdToSpec(tls.HelloFirefox_120)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return nil, fmt.Errorf("tls.UTLSIdToSpec error: %+v", err)
|
// return nil, fmt.Errorf("tls.UTLSIdToSpec error: %+v", err)
|
||||||
}
|
// }
|
||||||
|
|
||||||
err = uTlsConn.ApplyPreset(&spec)
|
// err = uTlsConn.ApplyPreset(&spec)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return nil, fmt.Errorf("uTlsConn.Handshake() error: %+v", err)
|
// return nil, fmt.Errorf("uTlsConn.Handshake() error: %+v", err)
|
||||||
}
|
// }
|
||||||
|
|
||||||
err = uTlsConn.Handshake()
|
err = uTlsConn.Handshake()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
153
u_conn.go
153
u_conn.go
|
@ -51,6 +51,9 @@ type UConn struct {
|
||||||
|
|
||||||
// ech extension is a shortcut to the ECH extension in the Extensions slice if there is one.
|
// ech extension is a shortcut to the ECH extension in the Extensions slice if there is one.
|
||||||
ech ECHExtension
|
ech ECHExtension
|
||||||
|
|
||||||
|
// echCtx is the echContex returned by makeClientHello()
|
||||||
|
echCtx *echContext
|
||||||
}
|
}
|
||||||
|
|
||||||
// UClient returns a new uTLS client, with behavior depending on clientHelloID.
|
// UClient returns a new uTLS client, with behavior depending on clientHelloID.
|
||||||
|
@ -107,7 +110,7 @@ func (uconn *UConn) buildHandshakeState(loadSession bool) error {
|
||||||
uAssert(uconn.clientHelloBuildStatus == NotBuilt, "BuildHandshakeState failed: invalid call, client hello has already been built by utls")
|
uAssert(uconn.clientHelloBuildStatus == NotBuilt, "BuildHandshakeState failed: invalid call, client hello has already been built by utls")
|
||||||
|
|
||||||
// use default Golang ClientHello.
|
// use default Golang ClientHello.
|
||||||
hello, keySharePrivate, _, err := uconn.makeClientHello()
|
hello, keySharePrivate, ech, err := uconn.makeClientHello()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -115,6 +118,7 @@ func (uconn *UConn) buildHandshakeState(loadSession bool) error {
|
||||||
uconn.HandshakeState.Hello = hello.getPublicPtr()
|
uconn.HandshakeState.Hello = hello.getPublicPtr()
|
||||||
uconn.HandshakeState.State13.KeyShareKeys = keySharePrivate.ToPublic()
|
uconn.HandshakeState.State13.KeyShareKeys = keySharePrivate.ToPublic()
|
||||||
uconn.HandshakeState.C = uconn.Conn
|
uconn.HandshakeState.C = uconn.Conn
|
||||||
|
uconn.echCtx = ech
|
||||||
uconn.clientHelloBuildStatus = BuildByGoTLS
|
uconn.clientHelloBuildStatus = BuildByGoTLS
|
||||||
} else {
|
} else {
|
||||||
uAssert(uconn.clientHelloBuildStatus == BuildByUtls || uconn.clientHelloBuildStatus == NotBuilt, "BuildHandshakeState failed: invalid call, client hello has already been built by go-tls")
|
uAssert(uconn.clientHelloBuildStatus == BuildByUtls || uconn.clientHelloBuildStatus == NotBuilt, "BuildHandshakeState failed: invalid call, client hello has already been built by go-tls")
|
||||||
|
@ -473,153 +477,6 @@ func (c *UConn) Write(b []byte) (int, error) {
|
||||||
return n + m, c.out.setErrorLocked(err)
|
return n + m, c.out.setErrorLocked(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// clientHandshakeWithOneState checks that exactly one expected state is set (1.2 or 1.3)
|
|
||||||
// and performs client TLS handshake with that state
|
|
||||||
func (c *UConn) clientHandshake(ctx context.Context) (err error) {
|
|
||||||
// [uTLS section begins]
|
|
||||||
hello := c.HandshakeState.Hello.getPrivatePtr()
|
|
||||||
defer func() { c.HandshakeState.Hello = hello.getPublicPtr() }()
|
|
||||||
|
|
||||||
sessionIsLocked := c.utls.sessionController.isSessionLocked()
|
|
||||||
|
|
||||||
// after this point exactly 1 out of 2 HandshakeState pointers is non-nil,
|
|
||||||
// useTLS13 variable tells which pointer
|
|
||||||
// [uTLS section ends]
|
|
||||||
|
|
||||||
if c.config == nil {
|
|
||||||
c.config = defaultConfig()
|
|
||||||
}
|
|
||||||
|
|
||||||
// This may be a renegotiation handshake, in which case some fields
|
|
||||||
// need to be reset.
|
|
||||||
c.didResume = false
|
|
||||||
|
|
||||||
// [uTLS section begins]
|
|
||||||
// don't make new ClientHello, use hs.hello
|
|
||||||
// preserve the checks from beginning and end of makeClientHello()
|
|
||||||
if len(c.config.ServerName) == 0 && !c.config.InsecureSkipVerify && len(c.config.InsecureServerNameToVerify) == 0 {
|
|
||||||
return errors.New("tls: at least one of ServerName, InsecureSkipVerify or InsecureServerNameToVerify must be specified in the tls.Config")
|
|
||||||
}
|
|
||||||
|
|
||||||
nextProtosLength := 0
|
|
||||||
for _, proto := range c.config.NextProtos {
|
|
||||||
if l := len(proto); l == 0 || l > 255 {
|
|
||||||
return errors.New("tls: invalid NextProtos value")
|
|
||||||
} else {
|
|
||||||
nextProtosLength += 1 + l
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if nextProtosLength > 0xffff {
|
|
||||||
return errors.New("tls: NextProtos values too large")
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.handshakes > 0 {
|
|
||||||
hello.secureRenegotiation = c.clientFinished[:]
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
session *SessionState
|
|
||||||
earlySecret []byte
|
|
||||||
binderKey []byte
|
|
||||||
)
|
|
||||||
if !sessionIsLocked {
|
|
||||||
// [uTLS section ends]
|
|
||||||
|
|
||||||
session, earlySecret, binderKey, err = c.loadSession(hello)
|
|
||||||
|
|
||||||
// [uTLS section start]
|
|
||||||
} else {
|
|
||||||
session = c.HandshakeState.Session
|
|
||||||
earlySecret = c.HandshakeState.State13.EarlySecret
|
|
||||||
binderKey = c.HandshakeState.State13.BinderKey
|
|
||||||
}
|
|
||||||
// [uTLS section ends]
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if session != nil {
|
|
||||||
defer func() {
|
|
||||||
// If we got a handshake failure when resuming a session, throw away
|
|
||||||
// the session ticket. See RFC 5077, Section 3.2.
|
|
||||||
//
|
|
||||||
// RFC 8446 makes no mention of dropping tickets on failure, but it
|
|
||||||
// does require servers to abort on invalid binders, so we need to
|
|
||||||
// delete tickets to recover from a corrupted PSK.
|
|
||||||
if err != nil {
|
|
||||||
if cacheKey := c.clientSessionCacheKey(); cacheKey != "" {
|
|
||||||
c.config.ClientSessionCache.Put(cacheKey, nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := c.writeHandshakeRecord(hello, nil); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if hello.earlyData {
|
|
||||||
suite := cipherSuiteTLS13ByID(session.cipherSuite)
|
|
||||||
transcript := suite.hash.New()
|
|
||||||
if err := transcriptMsg(hello, transcript); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
earlyTrafficSecret := suite.deriveSecret(earlySecret, clientEarlyTrafficLabel, transcript)
|
|
||||||
c.quicSetWriteSecret(QUICEncryptionLevelEarly, suite.id, earlyTrafficSecret)
|
|
||||||
}
|
|
||||||
|
|
||||||
msg, err := c.readHandshake(nil)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
serverHello, ok := msg.(*serverHelloMsg)
|
|
||||||
if !ok {
|
|
||||||
c.sendAlert(alertUnexpectedMessage)
|
|
||||||
return unexpectedMessageError(serverHello, msg)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := c.pickTLSVersion(serverHello); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// uTLS: do not create new handshakeState, use existing one
|
|
||||||
if c.vers == VersionTLS13 {
|
|
||||||
hs13 := c.HandshakeState.toPrivate13()
|
|
||||||
hs13.serverHello = serverHello
|
|
||||||
hs13.hello = hello
|
|
||||||
if hs13.keySharesParams == nil {
|
|
||||||
hs13.keySharesParams = NewKeySharesParameters()
|
|
||||||
}
|
|
||||||
if !sessionIsLocked {
|
|
||||||
hs13.earlySecret = earlySecret
|
|
||||||
hs13.binderKey = binderKey
|
|
||||||
hs13.session = session
|
|
||||||
}
|
|
||||||
hs13.ctx = ctx
|
|
||||||
// In TLS 1.3, session tickets are delivered after the handshake.
|
|
||||||
err = hs13.handshake()
|
|
||||||
if handshakeState := hs13.toPublic13(); handshakeState != nil {
|
|
||||||
c.HandshakeState = *handshakeState
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
hs12 := c.HandshakeState.toPrivate12()
|
|
||||||
hs12.serverHello = serverHello
|
|
||||||
hs12.hello = hello
|
|
||||||
hs12.ctx = ctx
|
|
||||||
hs12.session = session
|
|
||||||
err = hs12.handshake()
|
|
||||||
if handshakeState := hs12.toPublic12(); handshakeState != nil {
|
|
||||||
c.HandshakeState = *handshakeState
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (uconn *UConn) ApplyConfig() error {
|
func (uconn *UConn) ApplyConfig() error {
|
||||||
for _, ext := range uconn.Extensions {
|
for _, ext := range uconn.Extensions {
|
||||||
err := ext.writeToUConn(uconn)
|
err := ext.writeToUConn(uconn)
|
||||||
|
|
|
@ -7,6 +7,7 @@ package tls
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"compress/zlib"
|
"compress/zlib"
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
@ -383,3 +384,175 @@ func (c *Conn) makeClientHelloForApplyPreset() (*clientHelloMsg, *keySharePrivat
|
||||||
|
|
||||||
return hello, keyShareKeys, ech, nil
|
return hello, keyShareKeys, ech, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// clientHandshakeWithOneState checks that exactly one expected state is set (1.2 or 1.3)
|
||||||
|
// and performs client TLS handshake with that state
|
||||||
|
func (c *UConn) clientHandshake(ctx context.Context) (err error) {
|
||||||
|
// [uTLS section begins]
|
||||||
|
hello := c.HandshakeState.Hello.getPrivatePtr()
|
||||||
|
ech := c.echCtx
|
||||||
|
defer func() { c.HandshakeState.Hello = hello.getPublicPtr() }()
|
||||||
|
|
||||||
|
sessionIsLocked := c.utls.sessionController.isSessionLocked()
|
||||||
|
|
||||||
|
// after this point exactly 1 out of 2 HandshakeState pointers is non-nil,
|
||||||
|
// useTLS13 variable tells which pointer
|
||||||
|
// [uTLS section ends]
|
||||||
|
|
||||||
|
if c.config == nil {
|
||||||
|
c.config = defaultConfig()
|
||||||
|
}
|
||||||
|
|
||||||
|
// This may be a renegotiation handshake, in which case some fields
|
||||||
|
// need to be reset.
|
||||||
|
c.didResume = false
|
||||||
|
|
||||||
|
// [uTLS section begins]
|
||||||
|
// don't make new ClientHello, use hs.hello
|
||||||
|
// preserve the checks from beginning and end of makeClientHello()
|
||||||
|
if len(c.config.ServerName) == 0 && !c.config.InsecureSkipVerify && len(c.config.InsecureServerNameToVerify) == 0 {
|
||||||
|
return errors.New("tls: at least one of ServerName, InsecureSkipVerify or InsecureServerNameToVerify must be specified in the tls.Config")
|
||||||
|
}
|
||||||
|
|
||||||
|
nextProtosLength := 0
|
||||||
|
for _, proto := range c.config.NextProtos {
|
||||||
|
if l := len(proto); l == 0 || l > 255 {
|
||||||
|
return errors.New("tls: invalid NextProtos value")
|
||||||
|
} else {
|
||||||
|
nextProtosLength += 1 + l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if nextProtosLength > 0xffff {
|
||||||
|
return errors.New("tls: NextProtos values too large")
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.handshakes > 0 {
|
||||||
|
hello.secureRenegotiation = c.clientFinished[:]
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
session *SessionState
|
||||||
|
earlySecret []byte
|
||||||
|
binderKey []byte
|
||||||
|
)
|
||||||
|
if !sessionIsLocked {
|
||||||
|
// [uTLS section ends]
|
||||||
|
|
||||||
|
session, earlySecret, binderKey, err = c.loadSession(hello)
|
||||||
|
|
||||||
|
// [uTLS section start]
|
||||||
|
} else {
|
||||||
|
session = c.HandshakeState.Session
|
||||||
|
earlySecret = c.HandshakeState.State13.EarlySecret
|
||||||
|
binderKey = c.HandshakeState.State13.BinderKey
|
||||||
|
}
|
||||||
|
// [uTLS section ends]
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if session != nil {
|
||||||
|
defer func() {
|
||||||
|
// If we got a handshake failure when resuming a session, throw away
|
||||||
|
// the session ticket. See RFC 5077, Section 3.2.
|
||||||
|
//
|
||||||
|
// RFC 8446 makes no mention of dropping tickets on failure, but it
|
||||||
|
// does require servers to abort on invalid binders, so we need to
|
||||||
|
// delete tickets to recover from a corrupted PSK.
|
||||||
|
if err != nil {
|
||||||
|
if cacheKey := c.clientSessionCacheKey(); cacheKey != "" {
|
||||||
|
c.config.ClientSessionCache.Put(cacheKey, nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
if ech != nil {
|
||||||
|
// Split hello into inner and outer
|
||||||
|
ech.innerHello = hello.clone()
|
||||||
|
|
||||||
|
// Overwrite the server name in the outer hello with the public facing
|
||||||
|
// name.
|
||||||
|
hello.serverName = string(ech.config.PublicName)
|
||||||
|
// Generate a new random for the outer hello.
|
||||||
|
hello.random = make([]byte, 32)
|
||||||
|
_, err = io.ReadFull(c.config.rand(), hello.random)
|
||||||
|
if err != nil {
|
||||||
|
return errors.New("tls: short read from Rand: " + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: we don't do PSK GREASE, in line with boringssl, it's meant to
|
||||||
|
// work around _possibly_ broken middleboxes, but there is little-to-no
|
||||||
|
// evidence that this is actually a problem.
|
||||||
|
|
||||||
|
if err := computeAndUpdateOuterECHExtension(hello, ech.innerHello, ech, true); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c.serverName = hello.serverName
|
||||||
|
|
||||||
|
if _, err := c.writeHandshakeRecord(hello, nil); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if hello.earlyData {
|
||||||
|
suite := cipherSuiteTLS13ByID(session.cipherSuite)
|
||||||
|
transcript := suite.hash.New()
|
||||||
|
if err := transcriptMsg(hello, transcript); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
earlyTrafficSecret := suite.deriveSecret(earlySecret, clientEarlyTrafficLabel, transcript)
|
||||||
|
c.quicSetWriteSecret(QUICEncryptionLevelEarly, suite.id, earlyTrafficSecret)
|
||||||
|
}
|
||||||
|
|
||||||
|
// serverHelloMsg is not included in the transcript
|
||||||
|
msg, err := c.readHandshake(nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
serverHello, ok := msg.(*serverHelloMsg)
|
||||||
|
if !ok {
|
||||||
|
c.sendAlert(alertUnexpectedMessage)
|
||||||
|
return unexpectedMessageError(serverHello, msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := c.pickTLSVersion(serverHello); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// uTLS: do not create new handshakeState, use existing one
|
||||||
|
if c.vers == VersionTLS13 {
|
||||||
|
hs13 := c.HandshakeState.toPrivate13()
|
||||||
|
hs13.serverHello = serverHello
|
||||||
|
hs13.hello = hello
|
||||||
|
hs13.echContext = ech
|
||||||
|
if !sessionIsLocked {
|
||||||
|
hs13.earlySecret = earlySecret
|
||||||
|
hs13.binderKey = binderKey
|
||||||
|
hs13.session = session
|
||||||
|
}
|
||||||
|
hs13.ctx = ctx
|
||||||
|
// In TLS 1.3, session tickets are delivered after the handshake.
|
||||||
|
err = hs13.handshake()
|
||||||
|
if handshakeState := hs13.toPublic13(); handshakeState != nil {
|
||||||
|
c.HandshakeState = *handshakeState
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
hs12 := c.HandshakeState.toPrivate12()
|
||||||
|
hs12.serverHello = serverHello
|
||||||
|
hs12.hello = hello
|
||||||
|
hs12.ctx = ctx
|
||||||
|
hs12.session = session
|
||||||
|
err = hs12.handshake()
|
||||||
|
if handshakeState := hs12.toPublic12(); handshakeState != nil {
|
||||||
|
c.HandshakeState = *handshakeState
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -2626,7 +2626,7 @@ func (uconn *UConn) ApplyPreset(p *ClientHelloSpec) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
privateHello, clientKeySharePrivate, _, err := uconn.makeClientHelloForApplyPreset()
|
privateHello, clientKeySharePrivate, ech, err := uconn.makeClientHelloForApplyPreset()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -2637,6 +2637,7 @@ func (uconn *UConn) ApplyPreset(p *ClientHelloSpec) error {
|
||||||
uconn.HandshakeState.State13.KeyShareKeys = &KeySharePrivateKeys{}
|
uconn.HandshakeState.State13.KeyShareKeys = &KeySharePrivateKeys{}
|
||||||
}
|
}
|
||||||
uconn.HandshakeState.State13.KeySharesParams = NewKeySharesParameters()
|
uconn.HandshakeState.State13.KeySharesParams = NewKeySharesParameters()
|
||||||
|
uconn.echCtx = ech
|
||||||
hello := uconn.HandshakeState.Hello
|
hello := uconn.HandshakeState.Hello
|
||||||
|
|
||||||
switch len(hello.Random) {
|
switch len(hello.Random) {
|
||||||
|
|
|
@ -436,7 +436,8 @@ type PubClientHelloMsg struct {
|
||||||
PskBinders [][]byte
|
PskBinders [][]byte
|
||||||
QuicTransportParameters []byte
|
QuicTransportParameters []byte
|
||||||
|
|
||||||
cachedPrivateHello *clientHelloMsg // todo: further optimize to reduce clientHelloMsg construction
|
cachedPrivateHello *clientHelloMsg // todo: further optimize to reduce clientHelloMsg construction
|
||||||
|
encryptedClientHello []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func (chm *PubClientHelloMsg) getPrivatePtr() *clientHelloMsg {
|
func (chm *PubClientHelloMsg) getPrivatePtr() *clientHelloMsg {
|
||||||
|
@ -472,6 +473,7 @@ func (chm *PubClientHelloMsg) getPrivatePtr() *clientHelloMsg {
|
||||||
pskIdentities: PskIdentities(chm.PskIdentities).ToPrivate(),
|
pskIdentities: PskIdentities(chm.PskIdentities).ToPrivate(),
|
||||||
pskBinders: chm.PskBinders,
|
pskBinders: chm.PskBinders,
|
||||||
quicTransportParameters: chm.QuicTransportParameters,
|
quicTransportParameters: chm.QuicTransportParameters,
|
||||||
|
encryptedClientHello: chm.encryptedClientHello,
|
||||||
|
|
||||||
nextProtoNeg: chm.NextProtoNeg,
|
nextProtoNeg: chm.NextProtoNeg,
|
||||||
}
|
}
|
||||||
|
@ -523,6 +525,7 @@ func (chm *clientHelloMsg) getPublicPtr() *PubClientHelloMsg {
|
||||||
PskBinders: chm.pskBinders,
|
PskBinders: chm.pskBinders,
|
||||||
QuicTransportParameters: chm.quicTransportParameters,
|
QuicTransportParameters: chm.quicTransportParameters,
|
||||||
cachedPrivateHello: chm,
|
cachedPrivateHello: chm,
|
||||||
|
encryptedClientHello: chm.encryptedClientHello,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue